这在 C++ 中可能吗?
Posted
技术标签:
【中文标题】这在 C++ 中可能吗?【英文标题】:is this possible in C++? 【发布时间】:2009-07-07 05:21:56 【问题描述】:从一个类创建另一个类的实例,即使我想要创建一个实例的类是在我创建实例的类的下一个声明的。就像在 C# 和 Java 中一样。
谢谢
【问题讨论】:
【参考方案1】:您可以出于某些目的使用前向声明,但无论何时实际使用它,您都需要拥有完整的类型。建议将问题更具体地说明您真正想要实现的目标,因为可能有更简单的方法来解决您的问题(如果顺序很重要,它可能表明 A 类和 B 类之间存在循环依赖关系,这通常不是好)。
class B;
class A
public:
A( B b, B* bp, B& br ) : bp_(bp), br_(br) // ok, incomplete types can be used as argument types
B f()
// return B(); // nok: cannot create objects of incomplete type
;
B* f2() return bp_; // ok
B& f3() return br_; ; // ok
void g()
// bp_->g(); br_.g(); // nok: cannot call methods of an incomplete type
;
void g( B const & b )
// b.g(); // nok: cannot call methods of an incomplete type
private:
B * bp_; // ok (also const version)
B & br_; // ok (also const version)
// B b_; // nok: B must be a complete type here
;
class B // A is complete, any use is correct here
void g()
;
// From here on, B is a complete type and can be used in any possible way
B A::f()
return B(); // ok, now B is complete
void A::g()
br_.g(); // ok, B is complete here
bp_->g(); // ok, B is complete here
void A::g( B const & b )
b.g();
【讨论】:
【参考方案2】:当然。你只需要一个前向声明。像这样的东西很好用:
#include <iostream>
class B;
class A
public:
void hello( B &b );
void meow();
;
class B
public:
void hello( A &a );
void woof();
;
void A::hello( B &b ) b.woof();
void A::meow() std::cout << "Meow!" << std::endl;
void B::hello( A &a ) a.meow();
void B::woof() std::cout << "Woof!" << std::endl;
int main() A a; B b; a.hello( b ); b.hello( a ); return 0;
这里的关键是,在完全定义之前,您只能使用指向类的指针或引用。因此,在我给出的示例中,A 中的 hello() 方法可以声明 以获取对 B 的引用,即使此时我们还没有定义 B。但是在定义了B之后,方法A::hello()的定义就可以随意使用B了。
【讨论】:
嘿,这真的很有帮助!谢谢 “在完全定义之前,您只能使用指向类的指针或引用”。据我所知,您还可以在函数之间按值传递类... 破译这个问题的奖励在哪里?【参考方案3】:我猜你的意思是这样做:
class B; //Forward declaration
class A
private:
B b;
;
class B
;
这在 C++ 中是不可能的,因为编译器在编译 A 类时需要知道 sizeof(B)。
作为一种解决方案,您可以做的是:
class B; //Forward declaration
class A
public:
A();
~A();
private:
B* m_pB; //Store a pointer to B
;
class B
;
A::A()
m_pB = new B; //Create an instance of B
A::~A()
delete m_pB; //Explictly deallocate the memory.
m_pB = NULL;
【讨论】:
是的,我知道。但是如果我想访问该类的公共变量或函数怎么办? 但是相反的(A 刚好在 B 之下)会编译得很好。 @maxx:这仍然是不可能的,因为编译器只知道使用前向声明有一个称为 B 类的东西,但它不知道它的内容。 @Naveen: 不对,你只需要将A的成员函数声明放在一个.cpp文件中,并#include B的声明。【参考方案4】:在标头中转发声明 B 后,您可以在 .cpp 文件中使用它,而无需麻烦地访问公共变量和方法。
【讨论】:
以上是关于这在 C++ 中可能吗?的主要内容,如果未能解决你的问题,请参考以下文章
在 C++ 中使用默认参数跳过模板参数真的不可能吗,为啥语法建议不这样?