2015-10-16 6 views
0

Для начала я просто возвращаюсь на C++ с 20-ти летнего отсутствия. Я просто работаю над тем, чтобы выяснить кое-что. Я хочу создать иерархию классов и создать подклассы базового класса в список и перебрать в списке и вернуть подкласс в итератор или найти способ выполнить это.Boost ptr_list для доступа к методам подкласса

namespace FooBar { 

class ace { 
public: ace::ace(){}; 
public: virtual int ace::getValue(){ return 1; }; 
}; 

class base : public ace { 
public: base::base(){}; 

**// Added method for casting 
public: base::base(ace){};** 

public: int base::getValue(){ return 2; }; 
}; 

class face : public ace { 
public: face::face(){}; 

**// Added method for casting 
public: face::face(ace){};** 

public: int face::getValue(){ return 3; }; 
}; 
} 

Я создаю экземпляры соответствующего подкласса для вставки в список. Я не могу разобраться, как вернуть подкласс обратно из итератора. Я попытался добавить идентификатор, чтобы я знал, какой класс он был, но я не могу понять, как отличить итератор.

int main() { 
using namespace FooBar; 

boost::ptr_list<ace> theList; 
for (int i = 0; i < 10; i++){ 
    ace* foo; 
    if (i % 2 == 0) 
     foo = new base(); 
    else 
     foo = new face(); 
    theList.push_back(foo); 
} 

for (boost::ptr_list<ace>::iterator iter = theList.begin(); iter != theList.end(); iter++){ 
    std::cout << (*iter).getValue() << ", "; 

    // cast to sub class; Is it of type base 
    if (typeid(base) == typeid(*iter)){ 
     base bar = static_cast<base>(*iter); 
    } 
    else {typeid(face) == typeid(*iter)){ 
     face bar = static_cast<face>(*iter); 
    } 
} 
} 

выход 1, 1, ...

И бросает выше, не без какого-либо подходящего пользовательского преобразования из аса к основанию/лица существуют;

Итак, я создал конструктор как для основания, так и для лица, как показано в добавленном комментарии; и ошибка, которую я получаю сейчас:

ace :: ace (const ace &) не может быть ссылкой, это удаленная функция.

Любое руководство будет оценено по достоинству.

ответ

1

я не могу разобраться, как получить вспомогательный класс назад от итератора

Вы не можете, то, как вы в настоящее время он создан. C++ не имеет информации о типе времени выполнения (rtti), за исключением полиморфных классов (классы, которые имеют хотя бы одну виртуальную функцию).

Вы можете сделать getValue виртуальным (просто напишите virtual) и не нужно получать указатель на производный класс из указателя на базовый класс. Это было бы идиоматическим решением здесь.

Если вы на самом деле был случай, что вам необходимо, чтобы получить производный тип от указателя базового типа (и класс имел виртуальную функцию), вы можете использовать dynamic_cast или комбинацию typeid и static_cast, чтобы выяснить, что производный тип является.

+0

Спасибо, я пробовал вчера на работе, и мне не удалось добавить экземпляр в список, потому что он был виртуальным. Мне нужно будет увидеть, что отличается от этой сокращенной версии и решения, над которым я работаю. – Sting

+0

На самом деле у меня было две виртуальные функции-члены, и один был чистым виртуальным, поэтому я сделал оба виртуальных, и я прошел мимо этого момента. Я до сих пор не могу понять, как выполнить бросок. Я отредактировал этот вопрос, чтобы более подробно рассказать о проблеме. – Sting

Смежные вопросы