2015-11-30 3 views
0

Я следил за учебником по шаблону наблюдателя, и я столкнулся со следующей проблемой.Декларация класса Forward C++

А именно, у меня есть следующие базовые классы:

class Subject; 
class Observer; 

Далее, я хочу определить еще два класса

class StockGrabber: public Subject { 
    //... 
    //the constructor involves a StockObserver object 
    StockGrabber(StockObserver so){....}; 

} 
class StockObserver: public Observer { 
    //... 
    StockObserver(StockGrabber sg) {....}; 
} 

Есть ли способ, которым я мог бы использовать вперед декларацию, так что StockGrabber бы знать что существует StockObserver? Учитывая их взаимозависимость, я не мог просто поменять позиции двух классов.

Как мне решить эту проблему? (оригинальный учебник был написан на Java, но я пытаюсь реализовать его на C++) Спасибо!

+3

Эквивалентный код в Java будет означать ссылочную семантику, тогда как ваш код на C++ показывает семантику значений. Вероятно, вы захотите перейти на использование ссылочной семантики. Чтобы ответить на ваш вопрос, одно из тел функций должно быть определено вне очереди, чтобы использовать форвардные объявления. –

ответ

1

Вперед декларация недостаточно, вы должны внести некоторые изменения в подпись элемента управления StockObserver :: StockGrabber (StockObserver so), потому что если вы передаете аргумент по значению, вам нужно определение не только декларации параметров ' класс. Если вы передаете по ссылке, то объявления достаточно для объявления функции, но это объявление, конечно же, недостаточно для реализации этой функции, поэтому, возможно, вам придется определять функцию вне класса после определения класса StockObserver. Посмотрите на код ниже, это будет более понятным.

class Subject{ /* ... */ }; 
class Observer{ /* ... */ }; 

class StockObserver; 

class StockGrabber: public Subject { 
    //... 
    //the constructor involves a StockObserver object 
    StockGrabber(StockObserver& so); // class StockObserver is declared before StockGrabber::StockGrabber(StockObserver&). 
}; 

class StockObserver: public Observer { 
    //... 
    StockObserver(StockGrabber sg) { /* ... */ }; 
}; 

StockGrabber::StockGrabber(StockObserver& so){ /* ... */ } // class StockObserver is defined before StockGrabber::StockGrabber(StockObserver&). 
0

Да, вы можете использовать форвардную декларацию StockObserver. Следующая программа успешно завершается.

class Subject {}; 
class Observer {}; 

class StockObserver; 

class StockGrabber: public Subject { 
    StockGrabber(StockObserver so); 

}; 

class StockObserver: public Observer { 
    StockObserver(StockGrabber sg); 
}; 

StockGrabber::StockGrabber(StockObserver so) {} 

StockObserver::StockObserver(StockGrabber sg) {} 

int main() 
{ 
    return 0; 
} 

Непонятно, как вы хотите использовать аргументы для конструкторов. Будут проблемы при использовании аргументов конструкторам.

+0

@R_Sahu: спасибо, но когда я скомпилировал его, он дал ошибку «Variable имеет неполный тип« StockGrabber ». Любые подсказки? – Newbie

+0

Хотя это компилируется, фактически невозможно создать какие-либо экземпляры соответствующих классов. –

+0

@Newbie, см. Работу на http://ideone.com/xVArIY. –