【发布时间】:2009-07-07 05:21:56
【问题描述】:
从一个类创建另一个类的实例,即使我想要创建一个实例的类是在我创建实例的类的下一个声明的。就像在 C# 和 Java 中一样。
谢谢
【问题讨论】:
从一个类创建另一个类的实例,即使我想要创建一个实例的类是在我创建实例的类的下一个声明的。就像在 C# 和 Java 中一样。
谢谢
【问题讨论】:
您可以出于某些目的使用前向声明,但无论何时实际使用它,您都需要拥有完整的类型。建议将问题更具体地说明您真正想要实现的目标,因为可能有更简单的方法来解决您的问题(如果顺序很重要,它可能表明 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();
}
【讨论】:
当然。你只需要一个前向声明。像这样的东西很好用:
#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了。
【讨论】:
我猜你的意思是这样做:
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;
}
【讨论】:
在标头中转发声明 B 后,您可以在 .cpp 文件中使用它,而无需麻烦地访问公共变量和方法。
【讨论】: