C++ 错误:没有合适的默认构造函数
无法编译以下内容。这里怎么了C++ 错误:没有合适的默认构造函数,c++,constructor,default,C++,Constructor,Default,无法编译以下内容。这里怎么了 class B; class A { public: void DoSomething() { ... B* myb = new B(); ... } }; class B { public: B() {} }; new B()需要类型的完整定义。提前声明是不够的 这是有道理的。例如,谁说B甚至有一个公共默认构造函数?在知道B的完整定义之前,您无法知道。您执行转发声明是为了知道某些类B存在
class B;
class A
{
public:
void DoSomething()
{
...
B* myb = new B();
...
}
};
class B
{
public:
B() {}
};
new B()
需要类型的完整定义。提前声明是不够的
这是有道理的。例如,谁说
B
甚至有一个公共默认构造函数?在知道B
的完整定义之前,您无法知道。您执行转发声明是为了知道某些类B
存在,尽管它尚未定义。在这种情况下,您甚至不需要这样做,因为类A
中没有B
类型的成员
只需声明doSomething
方法,并在定义B
之后定义它
class A {
...
void doSomething(); // declared
...
};
class B {
...
};
// define doSomething after defining class B or in the .cpp source file
void A::doSomething() {
B *myb = new B();
...
}
虽然通常您会使用头文件/源文件,因此将声明与定义分开更为实际
编辑 如果A和B都相互引用,那么您需要在其中一个(或两者)中编写转发声明
转发声明允许您拥有指向该类型的指针,例如
B*
。但不是一个完整的类型B
,因为B
的大小未知,但B*
与任何其他指针的大小相同
通过在头文件中包含另一个类,可以使其中一个存储完整的类型,但不能同时包含这两个类
无论如何,如果您可以包含依赖的完整类型,那就没有意义了。然后
A
的一个实例将实例化一个成员B
,该成员将依次实例化其成员A
,依此类推。当您向前声明一个类型时,您告诉编译器存在这样一个类型。但是编译器不知道该类型的大小或成员
通常使用前向声明来打破循环依赖关系
class B;
class A
{
public:
void DoSomething()
{
...
B* myb ; ...
}
};
这将起作用,因为您只有一个指向该类型的指针
这里已经详细讨论了这一点:
上面的声明(正向声明)将名称B引入编译器。在声明之后和定义出现之前,类型B是一个不完整类型
不完整类型的使用受到限制。例如,可以为此类类型定义指针或引用。然而,这是不可能的
- 创建该类型的对象(编译器不知道类的大小)
- 访问该类型的成员(编译器不知道类的成员)
B* myb = new B();
在声明之后和定义出现之前。错误是什么,请放入整个代码。
B
的完整定义需要在创建实例之前可见。仅转发声明是不够的。C2512是错误代码。“'B':没有合适的默认构造函数可用”@Igor Tandetnik-我想你是对的。但如何解决这个问题呢?我正在尝试“状态模式”,具体的状态对象将在其公共方法中设置为另一个状态。如果B的定义不可见,状态对象如何将上下文状态设置为B?当然,在尝试创建它的实例之前,您可以通过使B
的定义可用来解决这个问题。我认为这是显而易见的。太棒了。这就是我必须做的。非常感谢你们向我们展示了一个非常简单且必须记住的技巧。
class B;
class A
{
public:
void DoSomething()
{
...
B* myb ; ...
}
};
class B;
B* myb = new B();