2010-10-27 4 views
0

У меня проблема с вызовом метода с l-значением абстрактного класса. Определение класса:с использованием l-значения с абстрактным классом

class SimulatorSequenceItemBase { 
public: 
    SimulatorSequenceItemBase(); 
    virtual ~SimulatorSequenceItemBase(); 

    virtual uint32_t GetResult(uint32_t p_nSite) = 0; 
    virtual bool MoveNext(SimulatorSequenceItemBase& p_rNext) = 0; 
} 

SimulatorSequenceItemBase имеет несколько подклассов. Существуют последовательности (для циклов) и элементы для цикла for.

Я хочу проходную последовательность и считать шаги, используя:

uint32_t nI = 0; 
SimulatorSequenceItemBase root = forSeq; // forSeq is an instance of a subclass of SimulatorSequenceItemBase 
while(root.MoveNext(root)) 
{ 
    ++nI; 
    std::cout << root.GetResult(0); 
} 

Корня Initally ссылки на корень, и на каждом вызов MoveNext, ссылка должна быть отрегулирована к следующему элементу.

Указанный выше код не работает, поскольку root не может быть выделен, так как тип корня является абстрактным. Но если я сделаю root указателем, то значение не может быть изменено в MoveNext.

Как это исправить? Все в порядке, чтобы изменить любой код, но идея должна оставаться неизменной.

+2

Интересно, кто 'nI' is –

+1

@Armen: Это секретный ник Николая Йосуттиса. ':)' – sbi

ответ

2

Я понятия не имею, что forSeq предполагается быть, но то, что случилось с

SimulatorSequenceItemBase& root = forSeq; // note that & 

Так, согласно комментарию, вам нужно сбросить root для обозначения различных объектов, вам придется использовать указатели :

SimulatorSequenceItemBase* root = forSeq; note the * 
while(root.MoveNext(root)) 
{ 
    // ... 
} 

Однако для того, чтобы иметь MoveNext() сброса root, он должен принимать указатель за ссылки:

bool MoveNext(SimulatorSequenceItemBase*& p_rNext) // note the *& 
+0

в соответствии с литературой: «После инициализации само refrence не может быть сделано, чтобы ссылаться на что-либо еще». (C++ Pocked Reference - Kyle Loudon - O'Reilly), что означает, что это не сработает для меня, поскольку я хочу отложить корень к различным элементам за итерацию. – Excel20

+0

@ Excel20: Ваш код не показывал, что вы хотите, чтобы «root» ссылался на разные объекты. Если вам нужно это сделать, вам нужно будет использовать указатель. Я отредактирую свой ответ. – sbi

0

OK, сначала. Почему MoveNext принимает аргумент вообще? Это не должно.

virtual bool MoveNext() = 0; 

, а затем

SimulatorSequenceItemBase& root = forSeq; 
while(root.MoveNext()) 
{ 
    ++nI; 
} 
1

Причина у вас есть проблема в том, что линия SimulatorSequenceItemBase root = forSeq; фактически создает новый экземпляр SimulatorSequenceItemBase на стеке (а сращивания копия forSeq). Поскольку у вас есть чистая виртуальная функция, вы не можете создать экземпляр базового класса. Что вам нужно сделать, это изменить его, чтобы использовать ссылку или указатель:

SimulatorSequenceItemBase *pRoot = &forSeq; 

while (pRoot->MoveNext(pRoot)) 
{ 
    ++nI; 
    std::cout << pRoot->GetResult(0); 
} 

Редактировать После Вашего комментария, я предлагаю рефакторинга кода, чтобы быть что-то вроде этого:

SimulatorSequenceItemBase *pNode = &forSeq; 
while (pNode != NULL) 
{ 
    ++nI; 
    std::cout << pRoot->GetResult(0); 

    pNode = pNode->MoveNext(); 
}; 
+0

в соответствии с литературой: «После инициализации сама ссылка не может быть использована для ссылки на что-либо еще». (C++ Pocked Reference - Kyle Loudon - O'Reilly), что означает, что это не сработает для меня, поскольку я хочу передать корень различным элементам за итерацию. – Excel20

+0

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

+0

, если вы выйдете из параметра, один присвойте указателю следующего элемента «this»? – Excel20

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