错误:没有适当的默认构造函数
无法编译以下内容。这里有什么不对?错误:没有适当的默认构造函数
class B;
class A
{
public:
void DoSomething()
{
...
B* myb = new B();
...
}
};
class B
{
public:
B() {}
};
new B()
要求完整的类型定义。前向声明是不够的。
这是有道理的。例如,谁说B
甚至有一个公共的默认构造函数?在B
的完整定义已知之前,您无法知道。
为了知道某些class B
存在,您做了前向声明,尽管它尚未定义。在这种情况下,您甚至不需要这样做,因为B
类型的class A
中没有成员。
刚刚宣布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都称呼对方,那么你需要写在其中的一个(或两个)正向声明。
// A.h
class B;
class A {
...
B *_myB;
};
// A.cpp
#include "B.h"
void A::doSomething() {
_myB = new B();
}
// B.h
class A;
class B {
...
A *_myA;
};
// B.cpp
#include "A.h"
void B::doSomething() {
_myA = new A();
}
预先声明可以让你有一个指针类型,如B*
。但不是完整的类型B
,因为B
的大小未知,但B*
与任何其他指针的大小相同。
您可以通过在头文件中包含其他类来存储完整类型,但不能同时包含这两种类型。
无论如何,如果您可以包含依赖完整类型,这是没有意义的。然后,A
的一个实例将实例化成员B
,该成员又将实例化其成员A
等等。
真棒。那就是我必须做的。非常感谢您向非常简单的技术展示灯光,并且必须记住技术。 – Anand
当你转发声明一个类型时,你告诉编译器这样一个类型exists.But编译器不知道该类型的大小或成员。
您通常使用前向声明来打破循环依赖关系。
class B;
class A
{
public:
void DoSomething()
{
...
B* myb ; ...
}
};
这将工作,因为你只有一个指向该类型的指针。
这已经在这里详细讨论: forward reference usage
class B;
上面的声明(向前声明)推出名称乙到编译器。声明之后并且在定义出现之前,键入B是不完整类型。
使用不完整类型是有限的。例如,指针或引用可以定义为这种类型。但是,这是不可能的;
- 创建(编译器不知道之类的大小)
- 访问类型的成员(编译器不知道班里有什么成员),该类型的对象
在有问题的代码中;
B* myb = new B();
是在声明之后并且在定义出现之前。
什么是错误,并把整个代码请。 – Bill
在创建它的一个实例之前,'B'的完整定义需要可见。单靠前向宣言是不够的。 –
C2512是错误代码。 “'B':没有适当的默认构造函数可用”@Igor Tandetnik - 我想你是对的。但如何解决这个问题? – Anand