C++默认构造函数

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

之前一直以为C++的默认构造函数,只要我们没有主动添加,编辑器都会默认合成。原来不是这样子的。而只在编译器需要的时候产生出来。具体是在什么时候需要?产生出来做什么事情?下面来看几个例子。

exp1:

class Foo { public: int a; int b};
void main()
{
	Foo foo;
	if(foo.a == 0)
		//do something
	...
}

这个例子中如果程序需要foo.a初始化为0,则需要程序员去实现。因为这是这是出于程序的需要,不是编辑器所需要的,所以需要人为去添加构造函数。

下面来看下编译器合成默认构造函数的几种情况:

1、“带有 Default Constructor” 的Member Class Object (成员类对象带有默认构造函数)

exp2:

class Foo { public: Foo();int a; int b};
class Bar { public: Foo foo; char ch;};
void main()
{
	Bar bar;//Bar::foo必须在此处初始化
	...
}
在这个例子中编译器会合成一个默认构造函数,该构造函数用来调用类Foo的默认构造函数来处理Bar::foo。

但这里并不对Bar::ch进行初始化,这是程序员要做的事情。
再考虑另一种情况,如果我们自己提供了默认构造函数:

//程序员定义的默认构造函数
Bar::Bar() { ch = '0';}
但是编译器还是要对Bar::foo初始化,显然不能再加一个默认构造函数。因此编译器就会在已有的默认构造函数插入部分代码。

可能会是这个样子:

//扩张后的默认构造函数
//C++伪代码
Bar::Bar() 
{
	foo.Foo::Foo();//编译器添加的代码
	ch = '0';
}
2、“带有 Default Constructor”的Base Class

exp3:

class A{
public:
	A(){};
};

class B:public A{

};
void main()
{
	B b;
	...
}
类B派生自类A,当B 实例化对象b时,编译器会合成一个类B的默认构造函数,通过该构造函数调用基类A的默认构造函数。

如果子类B中有多个构造函数,但都没有默认构造函数。则编译器会扩展现有的每个构造函数,加入相应的代码来调用基类A的默认构造函数。
3、“带有一个 Virtual Function”的Class

1.类声明(或继承)一个virtual function

2.类派生自一个或多个virtual base classes;
exp4:

class A{
public:
	virtual void fun() = 0;
};

class B:public A{

};
void main()
{
	B b;
	...
}
这里编译器同样会合成一个默认构造函数,这里的默认构造函数主要做:

1.创建虚函数表(vtbl),保存基类A的虚函数地址

2.保存虚函数表指针(vptr),指向虚函数表
4、“带有一个 Virtual Base Class”的Class

exp5:

class B:public virtual A{ public:	int j; };
class C:public virtual A{ public:	int d; };
void foo( const B* pb) { pb->i = 1; }
void main()
{
	foo( new B);
	...
}
在这个例子中编译器无法确定有pb而存取的X::i的实际偏移地址,因为pb的类型可变。因此编译器在子类B中安插一个指针_vbcA来存取基类A
在编译器中可能的代码样子:

void  foo ( const B* pb) { pb->_vbcA->i = 1; }
其中_vbcA指向虚基类A。如果子类B没有构造函数,这部分的工作也需要编译器合成一个默认构造函数。


总结

编译器合成默认构造函数的主要目的有:

1.调用基类的默认构造函数;

2.初始化虚函数机制或虚基类机制;

在合成的默认构造函数中只有 base class subobject 和member class objects会被初始化,其他的数据成员变量,如整数,数组等等都不会被初始化。

---学习《深入探索C++对象模型》笔记

C++构造函数默认参数使用 一代码 #include <iostream> using namespace std; class Box{ public: Box(int h=2,int w=2,int l=2);//在声明构造函数时指定默认参数 int volume(); private: int height,width,length; }; Box::Box(int h,int... 阅读详情

相关推荐

c++ 类的默认构造函数

保研之旅结束,现在可以按下心来学点以前没有时间深入学习的事情。以前为了写算法可以用c++的标准模板库,就学了c++,但是一直没有深入的学习下去,对c++的很多特性不是很熟。今天,来讲讲类的默认构造函数中的一些知识点。   首先,我创建了animal 类,代码如下: class animal{ private: int m_age; string m_sex; public: // a

2864

C++子类构造函数

构造函数是用来初始化类对象的。如果类中没有显式的声明构造函数,那么编译器会自动创建一个默认构造函数,并且这个默认构造函数仅仅在没有显式的声明构造函数的情况下才会被创建。 构造函数与父类的其它成员不同,它不能被子类继承。因此,在创建子类对象时,为了初始化从父类中继承来的成员变量,编译器需要调用其父类的构造函数。如果子类构造函数没有显式地调用父类的构造函数,则默认调用父类的无参构造函数,至于什么...

Vic_Hao的博客 1952

C++】类的默认构造函数

类的默认成员函数 文章目录类的默认成员函数1. 构造函数2. 默认构造函数 1. 构造函数 初始化类 函数名与类名相同 无返回值 对象实例化时编译器自动调用对应的构造函数 构造函数可以重载 我们测试一下对象实例化时编译器自动调用对应的构造函数 #include <iostream> using namespace std; class Date { public: //含参的构造函数 Date(int year = 0, int month = 0, int day = 0)

Rinne's blog 3167

C++类中无默认构造函数的情况

C++类中无默认构造函数的情况

qq_41317716的博客 1419

C++ 类“xxx”不存在默认构造函数

所以可以手动为Phone类添加上无参默认构造函数。即使将 Phone() 实现为空,也能避免编译错误,因为它告诉编译器,Phone 类有一个默认构造函数可以用来初始化 m_Phone 成员变量。c++中,在类中定义成员对象时,该成员类对象需要有默认构造函数,以告诉编译器如何将其初始化。由于这里的Sheep类已经构造了有参构造函数,编译器将不会自动构建无参默认函数。

qq_45285738的博客 3653

C++中父类和子类的构造析构关系

核心原则:子类的任何构造函数(无论无参还是有参)执行时,必须先调用父类的某个构造函数;自动调用的条件:仅当父类存在默认构造函数(无参或全默认参数),且子类构造函数未在初始化列表中显式调用父类其他构造函数时,才会自动调用父类的默认构造;显式调用的必要性:若父类不存在默认构造函数子类的任何构造函数(无参或有参)都必须在初始化列表中显式调用父类的带参构造函数,否则编译报错;灵活性:子类的有参构造函数可以通过初始化列表,将自身参数传递给父类的构造函数,实现父子类参数的联动。子类无法绕过父类的构造函数

weixin_66709931的博客 907

继承与派生【C++

继承与派生【C++】 一、概念 (1)基本概念 在 C++ 中可重用性是通过继承这一机制来实现的。因此,继承是 C++ 的一个重要组成部分。在 C++ 中,继承就是在一个已存在的类的基础上建立一个新的类。已存在的类称为 “基类” 或 “父类”。新建立的类称为 “派生类” 或 “子类”。 一个新类从已有的类那里获得其已有特性,这种现象称为类的继承。通过继承,一个新建子类从已有的父类那里获得父类的特性。从另一角度说,从已有的类(父类)产生一个新的子类,称为类的派生。 ...

qq_45783047的博客 1123

C++默认构造函数

摘要 默认构造函数(default constructor):类通过一个特殊的构造函数来控制默认初始化过程,这个函数称为默认构造函数默认构造函数无须任何实参。 合成的默认构造函数 如果我们的类没有显示地定义构造函数,那么编译器就会为我们隐式地定义一个默认构造函数。这个由编译器创建的构造函数又称为合成的默认构造函数(synthesized default constructor) 合成的默认构造...

zzy0006的博客 4226

C/C++编程:默认构造函数

默认构造函数 默认构造函数:是无参调用的构造函数,包括两种: 没有参数 每个参数有初始值 默认构造函数默认初始化和值初始化中得到调用。 默认初始化:在不使用初始化器构造变量时执行的初始化。 值初始化:在以空初始化器构造对象时进行的初始化 由来 先看下面代码 代码内容很简单,定义了一个包含成员x,y的类Point。在序列的地方可以使用这个类 虽然我们并没有定义Point类的构造函数,我们依然可以定义Point类的pt对象并使用它,其原因是编译器会自动生成一个缺省的构造函数,其效果相当于 但是,

OceanStar的博客 1万+

c++默认成员函数:构造函数|拷贝构造函数

本片博客为大家讲解构造函数|析构函数|拷贝构造函数c++中的作用。构造函数 :对于构造函数,我建议如果需要使用初始化,就去使用全缺省或者半缺省,虽然构造函数是成员函数,编译器会自动帮助我们生成默认构造函数,但是我们还是自己去初始化,虽然方便 但至少逻辑清晰,不会因为初始化的问题乱了方向。拷贝构造函数:如果使用拷贝构造函数,调用的时候一定要用引用!!!!!不然会无穷递归,死循环,也会默认拷贝,但不建议,

weixin_74163692的博客 1875

C++关于默认构造函数和无参构造函数

C++关于默认构造函数和无参构造函数 默认构造函数 在不提供任何构造函数的情况下,编译器给出一个不带参数的,不包含代码的构造函数。 #include<iostream> using namespace std; class A { public: int val; }; int main(){ A a; //这里调用的是默认构造函数 cout<<a.val<<endl; return 0; } 当已经提供了显式的构造函数,例如:

qq_38600065的博客 8803

C++默认构造函数——深入理解

错误认识1:若程序员没有自己定义无参数的构造函数,那么编译器会自动生成默认构造函数,来进行对成员函数的初始化。 错误认识2:编译器合成出来的default constructor会明确设定'“class内每一个data member的默认值”。但这两种种认识是有误的,不全面的。 正确认识: 默认构造函数分为有用的和无用的,所谓无用的默认构造函数就是一个空函数、什么操作也不做,而有用的默

HAN Kai 6万+

C++ 默认构造函数的重要性

1、默认构造函数 C++ 默认构造函数是对类中的参数提供默认值的构造函数,一般情况下,是一个没有参数值的空函数,也可以提供一些的默认值的构造函数,如果用户没有定义构造函数,那么编译器会给类提供一个默认构造函数,但是只要用户自定义了任意一个构造函数,那么编译器就不会提供默认构造函数,这种情况下,容易编译报错,所以正确的写法就是用户在定义构造函数的时候,也需要添加一个默认构造函数,这样就不会造

爱拍凯特的专栏 1万+

C++构造函数默认构造函数

参考博客:https://blog.csdn.net/china_jeffery/article/details/79288103#commentBox 以下内容是在上述博主的博客中提炼出来的: 一、默认构造函数的含义是啥: 主要就是:默认构造函数在调用的时候不需要显示传入实参的构造函数 二、默认构造函数的分类 1、无参构造函数:就是没有参数的构造函数 class Sample ...

Littlehero_121的博客 3090

C++编译器会对没有构造函数的类生成默认构造函数吗?

之前在上C++的课的时候,印象中有那么一句话: 如果一个类没有任何构造函数,那么编译器会生成一个默认构造函数 今天在看《深度探索C++对象模型》的第二章:“构造函数语意学”的时候发现之前听到的说法是错误的。 比如说如下代码: class A { public: int a; }; int main(void) { A a; a.a = 4; A a2; ...

个人博客 4851

C/C++ 关于默认构造函数

前言: 在C++中,对于一个类,C++的编译器都会为这个类提供四个默认函数,分别是: A() //默认构造函数 ~A() //默认析构函数 A(const A&) //默认拷贝构造函数 A& operator = (const A &) //默认赋值函数。 这四个函数如果我们不自行定义,将由编译器自动生成这四个缺省的函数,下面让我们来看看这四个函数(重点是后两个)。 ...

Mercury_cc的博客 2970

C++构造函数调用规则 ( 默认构造函数 | 默认无参构造函数 | 默认拷贝构造函数 | 构造函数调用规则说明 )

一、默认构造函数 1、默认无参构造函数 2、默认拷贝构造函数 二、构造函数调用规则 1、构造函数规则说明 2、代码示例 - 只定义拷贝构造函数 3、代码示例 - 只定义有参构造函数

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 6409

C++ 语言特性09 - 默认构造函数

C++中,POD是“Plain Old Data”的缩写,指的是最普通的C++数据类型和对象。POD类型包括了C++中的原始数据类型(如intdouble等)、POD结构体(不含用户定义的构造函数、虚函数、静态成员、引用成员等的类)、POD联合体、POD数组以及它们的数组。不包含用户自定义的构造函数:POD类型不能包含任何构造函数。不包含虚函数:POD类型不能包含任何虚函数。不包含静态成员变量:POD类型不能包含静态成员变量。不包含引用成员:POD类型不能包含引用类型的成员。不包含常量成员。

GPU全栈博主 1035
上一篇: hadoop学习--多表关联
下一篇: 设计模式学习-Strategy策略模式
我非英雄
博客等级 码龄16年 29粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值