2012-04-07 2 views
1

У меня есть следующие классы: Контейнер, Элемент, а затем пару классов, которые наследуют от элемента, например. Кнопка, Ввод и т.д ...полиморфизм и массив указателей (C++)

У меня есть проблема при добавлении элементов в массив Container, мой основной() выглядит следующим образом:

Container c; 
c.Add(Button(...)); 
c.Add(Input(...)); 

, где «...» некоторые конструктор параметры.

В классе контейнера У меня есть массив указателей для хранения всех элементов, которые принадлежат к этому контейнеру:

Element ** elements; 

Но проблема у меня в том, как реализовать метод Add, я надеялся, что-то как это будет работать:

void Add(const CControl & newElement){      
    elements[elemCnt++] = &newElement;    
} 

(массив элементов выделяются: элементы = новый элемент * [100];)

Однако я получаю эту ошибку компиляции:

main.cpp: In member function ‘Container& Container::Add(const Element&)’: 
main.cpp:138:23: error: invalid conversion from ‘const Element*’ to ‘Element*’ 

Когда я удаляю спецификатор const, я получаю ошибку компиляции, говоря, что подходящего кандидата нет.

Дело в том, что я новичок в полиморфизме и наследовании на C++, поэтому я могу ошибиться в этом. Какой был бы лучший подход к этому?

PS: Основной метод должен выглядеть одинаково, также не предлагайте никаких векторных или STL-материалов.

+0

Что случилось с использованием STL? Почему бы вам не использовать его ??? Это делает жизнь намного проще. –

+1

Здесь вы делаете одну серьезную ошибку, и она использует адрес переменной _temporary_ и сохраняет ее. Аргумент 'Add' является временным, и объект будет уничтожен после завершения вызова. Кроме того, я согласен с @TonyTheLion, почему бы не использовать очень хорошие стандартные контейнеры? –

+0

Скорее всего, мне нужно скопировать элемент и сохранить адрес динамически выделенной копии. Я не могу использовать STL, потому что это assigment, который тестируется в среде без STL. – Smaug

ответ

2

Add должен принимать указатель:

void Add(CControl * newElement){      
    elements[elemCnt++] = newElement;    
} 

, то вы можете назвать это как этот

c.Add(new Button(...)); 
c.Add(new Input(...)); 

Если вы действительно не можете изменить код вызова, необходимо каким-то образом создать копию временного , . путем осуществления виртуального метода Clone в CControl, Input, Button позвоните в Add.

void Add(const CControl & newElement){       
    elements[elemCnt++] = newElement.Clone(); 
} 
+0

'elements [elemCnt ++] = & newElement;' должны быть просто 'элементами [elemCnt ++] = newElement;'. –

+0

Проблема в том, что мне нужно иметь главное() как есть:/ – Smaug

+0

@JoachimPileborg - спасибо, отредактировал ответ. – Henrik

0

невозможно исправить этот код, не изменяя main, потому что вы пытаетесь сохранить ссылку на временный. Это отмена независимо от того, что вы делаете.

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