默认构造函数

作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/

关于默认构造函数的一些内容补充:

1.C++规定,每个类必须有默认的构造函数,没有构造函数就不能创建对象。

2.若没有提供任何构造函数,那么c++提供自动提供一个默认的构造函数,该默认构造函数是一个没有参数的构造函数,它仅仅负责创建对象而不做任何赋值操作。

3.只要类中提供了任意一个构造函数,那么c++就不自动提供默认构造函数。

4.类对象的定义和变量的定义类似,使用默认构造函数创建对象的时候,如果创建的是静态或者是全局对象,则对象的位模式全部为0,否则将会是随机的。

1.什么是默认构造函数?

一个函数是默认构造函数当且仅当调用它可以不需要传入任何参数。这个函数可以是用户自定义的,也可以是编译器产生的。【默认构造函数就是在没有显式提供初始化式时调用的构造函数。下边的各种构造函数都是默认构造函数。

struct A
{
int x;
A(): x(0) {}
};

struct B: A
{
//no user-defined ctor.
//the compiler implicitly declares a default constructor
};

class C
{
public:
explicit C(int n=0, int m=0); // may be invoked with no arguments
};

2.编译器什么时候隐式声明默认构造函数?

有两个条件:

  • 该类没有显式声明任何构造函数。--既然你都定义了,系统就不给你生成了。
  • 数据成员中没有const和reference。--因为要初始化。【注意,这块本人不是很理解,如果有const或者reference难道就不会隐式声明默认构造函数?为啥?那如果类成员还有其他类型数据需要初始化呢???】

满足则隐式生成默认构造函数。这里强调“任何”,是指即使用户自定义了复制构造函数或一个需要多个参数的构造函数,默认构造函数也不会被隐式声明了。

所以,在定义一个类时要保证有默认的构造函数。

3.隐式声明默认构造函数都干了什么?

什么都不做!确切的说,无论是隐式还是显式声明,都不意味着构造函数被定义。我们看看下边的情况:

class B
{
B(); //declaration only
};
B::B() {} //separate definition of the user-declared default constructor

class C
{
C() {} //declaration and definition
};
class D
{
//implicit declaration of a default constructor, no implicit definition
};
class E
{
//implicit declaration + implicit definition of a default constructor
virtual void f();
};
class F
{
virtual void f();
public:
F(); ////explicit declaration a default constructor, user forgot a definition
};

最后一种情况是常见的错误,用户忘记定义这个显式声明的默认构造函数,这会导致链接错误——用户自定义的默认构造函数必须实现,哪怕是空实现

我们注意到class D的情况隐式声明,但是没有隐式定义,既然没有隐式定义,那编译器何必隐式声明呢?

首先我们要进一步明确隐式声明和隐式定义的实质,这两个动作都是概念上的,编译器并非真的到你的头文件中插入了相关代码,只是编译器、连接器和程序的行为表现出好像进行了这样的动作。实际上,编译器就是设置了几个bit做了标识而已。之所以要进行隐式声明,编译器只是规定了一个类可以被如何使用(Each implicit declaration is like an article in a contract that states how a certain class may be used. When the compiler implicitly declares one of the special member functions, it grants certain authorizations to the user.)

4.什么时候编译器隐式定义一个隐式声明的默认构造函数?

在下列情况中的任何一种就会隐式定义:

  • 带有虚拟成员函数的类——完成vptr的初始化。
  • 子类——隐式执行基类默认构造函数。
#include
usingnamespace std;

class Bar
{
public:
Bar(){cout<< "Default constructor!"<< pre>
};

class Too:public Bar
{
};

//Foo::Foo(Bar bar):bar(bar){}

int main()
{
Too too1;
return 0;
}
  • 虚拟基类继承。

注:隐式定义的构造函数本身并不分配内存,它只是对一个类对象的初始而已,在声明对象时分配完内存,构造函数才被执行。并且也不对数据成员初始化。

原文链接: https://www.cnblogs.com/jiayouwyhit/p/3236040.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/98559

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月10日 上午4:48
下一篇 2023年2月10日 上午4:48

相关推荐