C++ 类缺省构造函数调用带参数的构造函数

本文介绍了C++中在缺省构造函数内调用带参数构造函数的情况。通过分析程序执行流程,揭示了这种调用方式会引发两次对象实例化,分别在栈上分配M1和M2空间,并执行构造函数和析构函数的过程。在缺省构造函数结束后,析构函数被调用释放内存,说明在缺省构造函数中调用带参构造函数并不影响原有空间的数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在看《effective C++:55 第三版》条款18:80页的时候,看到用外覆类型定义类型参数的例子:

class Month{
public:
    static Month Jan(){return Month(1);}
private:
    explicit Month(int num){val=num;}
    int val;
};
然后想到前几天做到的一个笔试题:

struct CLS
{
	int m_i;
	CLS(int i): m_i( i ) {   }
	CLS()
	{
		CLS( 0 );
	}
};

int main(void)
{
	CLS obj;
	cout << obj.m_i << endl;
	return 0;
}

这题的答案是,不能输出0,因为在默认构造函数内部再调用带参的构造函数属用户行为而非编译器行为,亦即仅执行函数调用,而不会执行其后的初始化表达式。只有在生成对象时,初始化表达式才会随相应的构造函数一起调用。

#include<iostream>
using namespace std;

class Month{
private:
	int val;
public:
	explicit Month(int num):val(num){<span style="white-space:pre">	</span>//a
	}<span style="white-space:pre">					</span>//b
	explicit Month(){<span style="white-space:pre">			</span>//c
		Month(1);<span style="white-space:pre">			</span>//d
	}<span style="white-space:pre">					</span>//e
	~Month(){<span style="white-space:pre">				</span>//f
		cout<<"val:"<<val<<endl;<span style="white-space:pre">	</span>//g
	}<span style="white-space:pre">					</span>//h
};
  
int main(void)  
{  
	Month A;<span style="white-space:pre">				</span>

    return 0;  
} 
这个程序的运行结果是这样的(32位机,win7系统):


但我预先设想的结果是只输出第二行的(也就是val未定义),不会输出第一行
跟踪了一下程序的运行轨迹,发现顺序是这样的:
1、在执行Month A;语句的时候,程序跳转到b处,继续往下执行,调用Month(1);语句

2、程序跳转到a处,执行完毕跳转回d处,往下执行到e处,程序跳转到f处,开始执行析构函数

3、执行完毕,程序跳至e处,继续执行,程序返回return 0;处

4、继续执行,程序又跳至f处,执行析构函数,执行完毕,程序跳回main函数,程序执行完毕;

通过以上程序执行过程,发现程序在缺省构造函数中执行Month(1);时,其实是相当于实例化对象(虽然没有名称),又一次在栈上分配了内存空间M2(前一次在栈上分配空间是执行Month A时,称为M1),并执行了构造函数Month(int num):val(num),同时执行了构造函数初始化列表将val初始化了。但此时是M2中的val初始化了,和M1中的val没有关系。

在执行完缺省构造函数Month()、程序退出Month()之前,由于之前调用了构造函数初始化对象,此时就必须调用析构函数,所以就有了程序的输出结果中的第一行结果;

程序返回main函数体之后,执行return 0;语句,预示着程序将会退出,这时再一次调用析构函数,所以就有了输出结果中的第二行结果,即val值没有初始化;


通过以上分析,我感觉对于笔试题而言,在缺省构造函数内部调用带参构造函数时,不是将带参构造函数当做普通函数执行函数调用,而是再一次实例化对象,在内存中重新开辟空间,并执行了带参构造函数后的初始化列表;但是在缺省构造函数执行完毕之后,预示着刚刚的实例化对象的生命周期的结束,程序调用析构函数释放了刚刚分配的内存空间;

也就是说:在缺省构造函数中调用带参构造函数,实际上是在一块新分配的栈空间中操作,对原有空间中的数据没有任何影响。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值