错误:没有适当的默认构造函数

问题描述:

无法编译以下内容。这里有什么不对?错误:没有适当的默认构造函数

class B; 
class A 
{ 
public: 
    void DoSomething() 
    { 
     ... 
     B* myb = new B(); 
     ... 
    } 
}; 

class B 
{ 
public: 
B() {} 
}; 
+1

什么是错误,并把整个代码请。 – Bill

+0

在创建它的一个实例之前,'B'的完整定义需要可见。单靠前向宣言是不够的。 –

+0

C2512是错误代码。 “'B':没有适当的默认构造函数可用”@Igor Tandetnik - 我想你是对的。但如何解决这个问题? – Anand

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等等。

+0

真棒。那就是我必须做的。非常感谢您向非常简单的技术展示灯光,并且必须记住技术。 – Anand

当你转发声明一个类型时,你告诉编译器这样一个类型exists.But编译器不知道该类型的大小或成员。

您通常使用前向声明来打破循环依赖关系。

class B; 
class A 
{ 
public: 
    void DoSomething() 
    { 
     ... 
     B* myb ;   ... 
    } 
}; 

这将工作,因为你只有一个指向该类型的指针。

这已经在这里详细讨论: forward reference usage

class B; 

上面的声明(向前声明)推出名称到编译器。声明之后并且在定义出现之前,键入B不完整类型

使用不完整类型是有限的。例如,指针或引用可以定义为这种类型。但是,这是不可能的;

  • 创建(编译器不知道之类的大小)
  • 访问类型的成员(编译器不知道班里有什么成员),该类型的对象

在有问题的代码中;

B* myb = new B(); 

是在声明之后并且在定义出现之前。