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();