类前向声明 C++
Posted
技术标签:
【中文标题】类前向声明 C++【英文标题】:Class Forward Declaration C++ 【发布时间】:2015-11-30 03:06:02 【问题描述】:我在学习观察者模式的教程时遇到了以下问题。
也就是说,我有以下基类:
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++ 实现它)谢谢!
【问题讨论】:
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&).
【讨论】:
【参考方案2】:是的,您可以使用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;
尚不清楚您希望如何使用构造函数的参数。使用构造函数的参数时会有挑战。
【讨论】:
@R_Sahu:谢谢,但是当我编译它时出现错误'变量的类型'StockGrabber'不完整。有什么提示吗?' 虽然可以编译,但实际上无法创建所涉及类的任何实例。 @R_Sahu,这只是因为构造函数只是默认的。假设如果填写详细信息,则会发生错误。方法是先进行前向声明,然后在类内部声明函数,在StockObserver类之后定义函数。 @Newbie,如果你能发布一个Minimal, Complete, and Verifiable example来解决这个问题就好了。 @R_Sahu 感谢您的意见。你的代码编译了,但我的代码没有编译,因为我在函数定义中有更多细节,有些变量直到代码后面才定义。以上是关于类前向声明 C++的主要内容,如果未能解决你的问题,请参考以下文章