`
weihe6666
  • 浏览: 440386 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

C++ 默认构造函数

    博客分类:
  • C++
C++ 
阅读更多
C++ 默认构造函数


一直认为若程序员没有自己定义无参数的构造函数,那么编译器会自动生成默认构造函数,来进行对成员函数的初始化,但这种认为是有误的,不全面的.

默认的构造函数分为有用的和无用的,所谓无用的默认构造函数就是一个空函数、什么操作也不做,而有用的默认构造函数是可以初始化成员的函数。

对构造函数的需求也是分为两类:一类是编辑器需求,一类是程序的需求。

程序的需求:若程序需求构造函数时,就是要程序员自定义构造函数来显示的初始化类的数据成员。

编辑器的需求:编辑器的需求也分为两类:一类是无用的空的构造函数,一类是编辑器自己合成的有用的构造函数。

在用户没有自定义构造函数的情况下:一、由于编辑器的需求,编辑器会调用空的无用的默认构造函数。二、但在下列情况下:编辑器就一定会合有用的默认构造函数。

看下面的例子:
#include <iostream>
using namespace std;

class Foo 
{
public: 
	int val; 
	Foo *pnext; 
}; 

void foo_bar() 
{ 
	// Oops:  program needs bar's members zeroed out 
	Foo bar; 
	if ( bar.val || bar.pnext ) 
	    cout << "Print the content !" << endl; 
} 

int main()
{
	foo_bar();
	return 0;
}

程序可以通过编译,但是显示:The variable 'bar' is being used without being initialized.

这就说明建立Foo bar; 这个对象编辑器并没有自动合成默认构造函数。

默认的构造函数也分为:有用的构造函数和无用的构造函数,所谓有用的构造函数就是构造函数会为我们的类做一些初始化的工作,而无用的构造函数对我们的类没有任何意义,我们常说的默认构造函数就是值有用的构造函数,英文为:nontrivial default constructor。

什么情况下编辑器才会自动合成有用的默认构造函数?(以下的默认构造函数均值有用的默认构造函数)

下面四种情况,编辑器才会背着用户自己合成默认构造函数:

一、带有“Default Constructor"的Member class Object.


如果一个类没有任何Constructor,但它内含一个带有Default Constructor的Member class Object。编辑器就会自动为此类合成一个默认的构造函数。

看下面的例子:
#include<iostream>
using namespace std;

class Foo 
{ 
public: 
	Foo(); 
	Foo( int );
private:
	int val;
}; 

Foo::Foo()
{
  cout << "Call Foo::Foo() Constructor !"<< endl;
  val = 0;
}

Foo::Foo(int i)
{
  cout << "Call Foo::Foo(int i) Constructor !"<< endl;
  val = i;
}

class Bar 
{ 
public: 
	Foo foo; 
	char *str; 
}; 

void foo_bar() { 
	Bar bar; // Bar::foo must be initialized here 
	if (bar.str ) 
	{
		cout << "Print the content !" << endl;
	} 
} 


int main()
{
	foo_bar();
	return 0;
}

输出为:
Call Foo::Foo() Constructor !
Print the content !

类class Bar 没有自己定义的Constructor,而成员中的Foo foo; 却带有字定义的Constructor(Foo::Foo()),这种情况符合:"带有“Default Constructor"的Member class Object."

由输出结果可以看出:编辑器为class Bar合成了默认的构造函数,并调用了Foo的自定义构造函数。

那么编辑器为class Bar合成了默认的构造函数应该是什么样子呢?
inline Bar::Bar()
{
 foo.Foo::Foo();
}

编辑器会自动合成如上的默认构造函数。

如果一个类自定义了Constructor,但它内含一个带有Default Constructor的Member class Object。编辑器就会自动扩充此类的自定义构造函数。

如果类Bar自定义了构造函数,那么编辑器会怎么做,如下代码:
class Bar 
{ 
public: 
	Bar();
	Foo foo; 
	char *str; 
}; 

Bar::Bar()
{
    cout << "Call Bar::Bar() Constructor !"<< endl;
	str = 0;
}

输出为:
Call Foo::Foo() Constructor !
Call Bar::Bar() Constructor !

看到输出结果仍然是调用了Foo的自定义的构造函数”Call Foo::Foo() Constructor !“。
那么这是如何做到的呢?

编辑器会扩充Bar自定义的构造函数,其结构如下:
Bar::Bar()
{
 foo.Foo::Foo();  //这里是编辑器自动添加上去的
   cout << "Call Bar::Bar() Constructor !"<< endl;
  str = 0;
}


二、如果派生列的基类中有自定义的nontrivial default constructor,那么编辑器会为每一个派生类合成一个nontrivial default constructor,以调用基类自定义的nontrivial default constructor。

三、如果一个类里隐式的含有Virtual tabel(Vtbl)或者pointer member(vptr)

vtbl或vptr需要编辑器隐式的合成出来,那么编辑器就把合成动作放在了默认构造函数里,所以编辑器必需自己产生一个构造函数来完成这些动作。

所以你的类里只要含有virtual function,那么编辑器就会生成默认的构造函数。

四、如果一个类虚继承与其他类

理由和上面一样,虚基类也需要vtbl和vptr管理,那么这些管理就需要合成构造函数来实现管理,则需要生成默认的构造函数。

所以类的基类有虚类,那么编辑器就会合成默认的构造函数。
分享到:
评论

相关推荐

    C++默认构造函数.pdf

    但是,C++默认构造函数的行为和使用规则却经常被程序员所误解和忽视。在本文中,我们将详细介绍C++默认构造函数的概念、使用规则和错误认识。 1. 默认构造函数的定义 C++默认构造函数是一个无参构造函数,它的主要...

    详解C++中构造函数,拷贝构造函数和赋值函数的区别和实现

    C++中一般创建对象,拷贝或赋值的方式有构造函数,拷贝构造函数,赋值函数这三种方法。下面就详细比较下三者之间的区别以及它们的具体实现 1.构造函数 构造函数是一种特殊的类...而默认构造函数没有参数,它什么也不做

    对C++默认构造函数的一点重要说明

    大多数C++书籍都说在我们没有自己定义构造函数的时候,编译器会自动生成默认构造函数。其实这句话我一直也是 深信不疑。但是最近看了一些资料让我有了一点新的认识。 其实我觉得大多数C++书籍之所以这样描述其实是玩...

    C++默认构造函数的问题

    C++ defaul construct :缺省构造函数(默认构造函数)  定义:第一种 构造函数没有参数,即是 A()形式的  第二种 构造函数的全部参数由缺省值提供,A(int a=0,int b=0)  编译器添加的默认构造函数的条件...

    构造函数与默认构造函数

    构造函数与默认构造函数的声明、定义、应用、比较

    详解在C++中显式默认设置的函数和已删除的函数的方法

    在 C++ 中,如果某个类型未声明它本身,则编译器将自动为该类型生成默认构造函数、复制构造函数、复制赋值运算符和析构函数。这些函数称为特殊成员函数,它们使 C++ 中的简单用户定义类型的行为如同 C 中的结构。也...

    C++复制构造函数详解

    此外,复制构造函数与默认构造函数、析构函数和赋值运算符一起构成了C++的特殊成员函数,这些函数对对象生命周期的管理起着关键作用。熟练掌握这些函数的使用,能够帮助开发者编写出更加安全、可维护的代码。

    C++简单类(构造函数,析构函数以及拷贝构造函数)的实现

    1. **默认构造函数**:`cPerson::cPerson()`,当没有提供任何参数来创建`cPerson`对象时,会调用这个构造函数。它默认初始化所有数据成员。 2. **带参数的构造函数**:此代码片段中未直接展示,但可以添加以接受...

    C++构造函数重载

    在这个例子中,`Circle()`是默认构造函数,没有参数,而`Circle(double r)`是带参数的构造函数,接收一个double类型的参数`r`来设定圆的半径。当我们创建`Circle`对象时,可以根据需求选择合适的构造函数: ```cpp ...

    c++构造函数小测验

    Student类定义了一个默认构造函数和一个接受整数和字符串引用作为参数的构造函数。在C++中,构造函数是一种特殊成员函数,它在创建对象时被自动调用,用以初始化对象。默认构造函数是在没有任何参数时被调用的构造...

    C++构造函数初始化列表

    1. **默认构造函数的隐式初始化**:如果没有提供显式的初始化,编译器会使用默认构造函数来初始化成员变量,这可能不是预期的行为。 2. **const成员变量的强制初始化**:对于声明为const的成员变量,必须在构造函数...

    c++构造函数实例质料

    然而,当我们在类中定义了构造函数,即使是无参数的,编译器就不会再提供默认构造函数,因此,`Student a;`这样的对象创建将会使用这个自定义的无参数构造函数。 接着,我们看到一个带参数的构造函数,即`Teacher`...

    c++ 类的定义 和构造函数

    1. **默认构造函数**:无参数的构造函数称为默认构造函数,如果没有显式定义,编译器会自动提供一个默认构造函数。 ```cpp class Person { public: Person() : age(0), name("") {} // 默认构造函数 private: ...

    c++中拷贝构造函数实例

    - **浅复制**:如果类的成员变量是基本类型(如int、double)或指针,拷贝构造函数默认执行浅复制,即只复制指针本身,不复制指针所指向的数据。这样,新旧对象共享同一块内存,修改一个对象可能会影响另一个。 - **...

    从汇编看c++中默认构造函数的使用分析

    }上面的类X没有定义构造函数,仅仅有一个int i。 下面为其汇编程序: 代码如下:; 7 : int main() {  push ebp;ebp为一个寄存器,总是指向一个函数调用堆栈的栈底,作为基址,用偏移量来访问该调用栈上的变量,但...

    c++ 子类构造函数初始化及父类构造初始化的使用

    "C++ 子类构造函数初始化及父类构造初始化的使用" C++ 中的构造函数初始化是指在类对象创建时对其进行初始化的过程。构造函数是类的特殊成员函数,用于初始化类对象。在 C++ 中,子类构造函数的初始化涉及到父类...

Global site tag (gtag.js) - Google Analytics