您的位置:首页 > 编程语言 > C语言/C++

C++编译器何时为用户提供默认构造函数

2013-03-27 23:58 225 查看
"说是如果程序员没有自己定义默认构造函数,那么编译器会自动为我们产生一个默认的构造函数。"这句话其实是不准确的。并不是所有的时候编译器都会为我们创建一个默认构造函数。

第一种是类成员中有成员是类对象,并且该成员的类含有默认构造函数,那么C++编译器会帮你给这个类也生成一个默认构造函数,用来调用其成员对象的构造函数,完成该成员的初始化构造。需要强调的是,如果这个成员的类也没有给出默认构造函数,那么C++编译器也不会帮你生成该类的默认构造函数。

  第二种情况是这个类的基类有默认构造函数。那么C++编译器也会帮你生成该派生类的默认构造函数,以调用基类的默认构造函数,完成基类的初始化。另外还得强调一下的是,如果基类没有提供这个默认构造的函数,那么C++编译器也不会为派生类生成默认的构造函数(这里包括两层意思,第一,基类没有任何形式构造函数;第二,基类存在其他形式的非默认构造函数,当然了,这种类型就是编译不过的,道理很明显)。

  第三种情况是类中存在虚函数,那么C++编译器会为你生成默认构造函数,以初始化虚表(虚函数表vftable)。

  第四种情况是存在虚基类,那么C++编译器会为你生成默认构造函数,以初始化虚基类表(vbtable)。

第5种是
当你使用静态分配的数组,而数组元素类型是某个类的对象时,就要调用默认的构造函数,比如下面的代码。

Object buffer[10]; // call default constructor


当你使用动态分配的数组,而数组元素类型是某个类的对象时,就要调用默认的构造函数,比如下面的代码,如果Object没有默认的构造函数,是无法通过编译的,因为new操作符要调用Object类个无参构造函数类初始化每个数组元素。

Object* buffer = new Object[10];


当你使用标准库的容器时,如果容器内的元素类型是某个类的对象时,那么这个类就需要默认的构造函数,原因同上。

vector<Object> buffer;


  

下面的例子中,就是因为基类A中没有提供默认构造函数,导致编译无法通过,为基类A添加上默认的构造函数后,编译就通过了。

#include "iostream"

using namespace std;

class A

{

public:

A() { } //基类添加上默认构造函数就可以了

A(int c)

{

x=c;

cout<<"A"<<endl;

}

void fun()

{

cout<<"in A fun"<<endl;

}

private:

int x;

};

class B:public A

{

public:

B(int c)

{

y=c;

cout<<"B"<<endl;

}

void fun()

{

cout<<"in B fun"<<endl;

}

private:

int y;

};

int main(void)

{

A *a=new B(2);

system("pause");

return 0;

}
一个类A以另外某个类B的对象为成员时,如果A提供了无参构造函数,而B提供,那么A则无法使用自己的无参构造函数。下面的代码将导致编译错误。

class B
{
B(int i){}
};

class A
{
A(){}
B b;
};

int main(void)
{
A a(); // error C2512: 'B' : no appropriate default constructor available

getchar() ;
return 0 ;
}


再比如下面的代码,类A定义了拷贝构造函数,而没有提供默认的构造函数,B继承自A,所以B在初始化时要调用A的构造函数来初始化A,而A没有默认的构造函数,故产生编译错误。

class A
{
A(const A&){}
};

class B : public A
{

};

int main(void)
{
B b; //error C2512:'B': no appropriate default constructor available

getchar() ;
return 0 ;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐