c++中六种构造函数的实现以及9中情况下,构造函数的调用过程

六种构造函数的实现代码如下:

#include<iostream>
using namespace std;
//c++中六种默认的构造函数
class Test
{
public:
	Test(int d = 0):m_data(d)//1构造函数(带默认值0),以参数列表的形式初始化
	{
		cout<<"Creat Test Obj :"<<this<<endl;
	}
	~Test()//2析构函数
	{
		cout<<"Free Test Obj :"<<this<<endl;
	}
	Test(const Test &t)//3拷贝构造函数:以对象初始化对象
	{
		cout<<"Copy Test Obj :"<<this<<endl;
		m_data = t.m_data;
	}
	Test& operator=(const Test &t)//4赋值语句
	{
		cout<<"Assgin:"<<this<<":"<<&t<<endl;
		if(this != &t)
		{
			m_data = t.m_data;
		}
		return *this;
	}
	Test* operator&()//5对象取址
	{
		return this;
	}
	const Test* operator&()const//6常对象取址
	{
		return this;
	}
	int GetData()
	{
		return m_data;
	}
private:
	int m_data;
};

下面介绍9种情况下构造函数的调用过程:

情况一:

//1
Test fun(Test t)
{
	int value = t.GetData();
	Test tmp(value);
	return tmp;
}

int main()
{
	Test t(10);
	Test t1;
	t1 = fun(t);
	return 0;
}

情况二:

//2
Test fun(Test t)
{
	int value = t.GetData();
	return Test(value);
}

int main()
{
	Test t(10);
	Test t1;
	t1 = fun(t);
	return 0;
}

情况三:

//3
Test fun(Test &t)
{
	int value = t.GetData();
    Test tmp(value);
	return tmp;
}

int main()
{
	Test t(10);
	Test t1;
	t1 = fun(t);
	return 0;
}

情况四:

//4
Test fun(Test &t)
{
	int value = t.GetData();
	return Test(value);
}

void main()
{
	Test t(10);
	Test t1;
	t1 = fun(t);
}

情况五:

//5
Test& fun(Test &t)
{
	int value = t.GetData();
	Test tmp(value);
	return tmp;
}

void main()
{
	Test t(10);
	Test t1;
	t1 = fun(t);
}

情况六:

//6
Test& fun(Test &t)
{
	int value = t.GetData();
	return Test(value);
}

void main()
{
	Test t(10);
	Test t1;
	t1 = fun(t);
}

情况七:

//7
Test fun(Test &t)
{
	int value = t.GetData();
	return Test(value);
}

void main()
{
	Test t(10);
	Test t1 = fun(t);
}

情况八:

//8
Test fun(Test &t)
{
	int value = t.GetData();
	Test tmp(value);
	return tmp;
}

void main()
{
	Test t(10);
	Test t1 = fun(t);
}

情况九:

Test& fun(Test &t)
{
	int value = t.GetData();
	Test tmp(value);
	return tmp;
}

void main()
{
	Test t(10);
	Test t1;
	t1 = fun(t);
}

综上所述:

一:调用拷贝构造函数的情况:

1)直接用对象初始化对象

2)形参数对象时,用实参对象初始化

3)函数的返回值类型是类时(非引用)是,拷贝构造无名的临时空间作为函数返回值

二:注意:

当函数的返回值是该函数中的一个临时对象时,函数类型不可以定义为Test &即引用,否则会发生,用一个已经析构的临时对象初始化另外一个对象,会发生错误;

三:提高效率的方式:

1)形参用引用,不再调用拷贝构造函数

2)返回一个无名的临时对象a,系统不再创建另外的一个临时对象而直接将a作为返回值,(函数返回类型不是引用)

3)返回无名的临时对象,且用它初始化另外一个对象,如情况七,直接将无名的对象作为另外的一个对象

4)上述三种情况结合;

时间: 2024-10-06 01:15:17

c++中六种构造函数的实现以及9中情况下,构造函数的调用过程的相关文章

C++学习之构造函数和拷贝控制--什么样的情况下才需要虚析构函数

什么样的情况下才需要虚析构函数? 类需要控制自己的对象执行一系列操作时发生什么样的行为,这些操作包括:创建(对象).拷贝.移动.赋值和销毁.在继承体系中,如果一个类(基类或其派生的类)没有定义拷贝控制操作,则编译器将自动的为其合成一个.即为合成的拷贝控制. 在基类的拷贝控制中,由于继承关系导致的最大影响就是:基类通常应该定义一个‘虚析构函数’.用以动态的分配继承体系中的对象. 如:类A,B,C,D有如下继承关系(代码1): 1 2 3 4 class A; class B:public A; c

多线程生产者、消费者模式中,如何停止消费者?多生产者情况下对“毒丸”策略的应用。

生产者.消费者模式是多线程中的经典问题.通过中间的缓冲队列,使得生产者和消费者的速度可以相互调节. 对于比较常见的单生产者.多消费者的情况,主要有以下两种策略: 通过volatile boolean producerDone =false 来标示是否完成.生产者结束后标示为true, 消费者轮询这个变量来决定自己是否退出. 这种方式对producerDone产生比较大的争用,实现起来也有诸多问题需要考虑. 比较经典的"毒丸"策略,生产者结束后,把一个特别的对象:"毒丸&quo

IE 中单元格的 colspan 属性在某些情况下会影响 TABLE 元素的自动布局

今天在写一个jsp页面时,遇到一个如下的问题:在一个table中写了如下内容,table中定义了4列,在firefox中能正常显示,而在ie8中,显示不正常, 如下如图1:第二,三,四列宽度发生变化,和代码中定义的宽度显示不一致, 图1(IE8): 图2(firefox): 代码如下: 1 <table id="cont2"> 2 <tbody> 3 <tr> 4 <td class="ct_t"> 5 是否分包<

构造函数的继承--子类不继承父类的构造函数,只能调用

关于子类对父类构造函数的继承: 子类必须调用父类的构造函数.默认情况下会自动调用父类的无参构造函数.如果父类没有无参构造函数,则必须显式的用super()调用一个构造函数. 创建对象时,先调用父类的构造函数对对象进行初始化, 然后再调用子类自己的构造函数 子类只继承(其实是默认调用)父类的默认(无参)构造函数,如果父类重写了自己的构造函数,就会导致父类没有无参构造函数,这样子类就不能从父类继承构造函数.

在jsp中选中checkbox后 将该记录的多个数据获取,然后传到Action类中进行后台处理 双主键情况下 *.hbm.xml中的写法

在jsp中选中checkbox后 将该记录的多个数据获取,然后传到Action类中进行后台处理 双主键情况下 *.hbm.xml中的写法 ==========方法1: --------1. 选相应的checkbox后  点删除按钮------------- <!-- *******************删除******************* -->     <input type="image" alt="delete"      src=&

在Spring的项目中配置Log4j存放日志文件到指定目录下

在Spring中使用LOG4J为日志输出的插件已有一段日子了,但有时候发现日志文件虽然是已经在根据自己的理想存放了,但还会有些莫名其妙的项目日志文件出现tomcat内(因为项目的日志文件都以项目命名嘛,所以比较容易区分这些log).这些令我纠结的日志文件,让我在改善一下LOG4J的配置.才发现,之前用的配置方式真是弱爆了. 1.先说自己比较理想的存放日志路径. 我比较喜欢把日志文件放在项目的WEB-INF下,然后当然有个文件夹叫logs.logs相信很多人都会存在在这样的目录下,但放在WEB-I

父类的构造函数在对象的生命中扮演的角色

在创建新对象时,所有继承下来的构造函数都会被继承 这代表着每个父类都有一个构造函数(因为每个类至少都会有一个构造函数),并且每个构造函数都会在对象创建时执行. 执行new的指令是个大事件,因为他会启动构造函数的连锁反应.还有,就算是抽象的类也有构造函数.虽然你不能对抽象函数执行new操作,但是抽象函数还是父类,因此它的构造函数会在具体的子类创建实例时被执行. 在构造函数中用super调用父类的构造函数部分(注意:调用super() 方法是调用父类构造函数的唯一方法).要记得子类会根据父类的状态进

JS中六种数据类型(六)——Object(转)

ECMAScript中的对象是可变的键控集合(即一组数据和功能的集合).它将很多值聚合在一起,可通过名字访问这些值.对象也可看做属性的容器,每个属性都是一个名/值对.属性的名字可以是包括空字符串在内的任意字符串.属性值可以是除undefined值之外的任何值.对象最常见的用法是创建(create).设置(set).查找(query).删除(delete).检测(test)和枚举(enumerate)他的属性.  一.属性类型 ECMA-262第5版在定义只有内部采用的特性时,描述了属性的各种特征

JS中六种数据类型(六)——Object

   ECMAScript中的对象是可变的键控集合(即一组数据和功能的集合).它将很多值聚合在一起,可通过名字访问这些值.对象也可看做属性的容器,每个属性都是一个名/值对.属性的名字可以是包括空字符串在内的任意字符串.属性值可以是除undefined值之外的任何值.对象最常见的用法是创建(create).设置(set).查找(query).删除(delete).检测(test)和枚举(enumerate)他的属性.  一.属性类型 ECMA-262第5版在定义只有内部采用的特性时,描述了属性的各