栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++中的构造函数、析构函数以及拷贝构造函数

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++中的构造函数、析构函数以及拷贝构造函数

只要创建了一个类编译器会默认创建三个构造,
1.无参构造
2.有参构造
3.拷贝构造
这三个函数你不写编译器就自动用编译器默认的,你写了就用你的。

// 构造函数和析构函数
// 类实例化一个对象时强制调用构造函数,对象销毁后自动调用析构函数进行清理工作。
// 如果没有手动写出构造和析构函数,编译器会自动补上,只不过是空实现。
#include 
using namespace std;


class fun {

public: // 如果私有化 则该类将不能在外部实例化对象
	fun() { // 没有返回值也不写void
		// 构造函数一般进行初始化的工作。
		// 可以有形参,可以重载,有参数的是有参构造,该构造为无参构造
		// 创建对象时会自动调用构造且只会调用一次。
		cout << "构造函数被调用!" << endl;
	}

	fun(int a) {
		cout << "有参构造 " << a << endl;
	}

	// 析构函数 语法  " ~类名(){} "
	~fun() {// 没有返回值也不写void
		// 析构函数进行清理工作。
		// 析构函数没有形参,不能发生重载。
		// 析构函数在对象死亡的时候被自动调用且只调用一次。
		cout << "析构函数被调用!" << endl;
	}
};

class Person {
	int age;
	
public:
	// 普通构造函数
	Person(){
	
	}
	Person(int a) {
	
	}
	// 拷贝构造函数 
	// 不写拷贝构造函数时,系统默认提供,拷贝p的所有属性到新的对象中
	Person(const Person& p) {
		// 拷贝时不能修改本体所以要写const
		age = p.age;
	}
};

// 调用
void test(){
	Person p1;  // 默认构造的调用
	// 1.括号法
	Person p2(10); // 调用有参构造函数
	Person p3(p2); // 括号法调用拷贝构造函数

	// 注意:1、调用默认构造时 不要加括号。
	// Person pp(); // 编译器认为这是函数的声明,而不是创建对象。
	
	
	
	// 2.显示法
	Person p4 = Person(10); // 调用有参构造
	Person p5 = Person(p4); // 显示法调用拷贝构造

	Person(10); // 创建匿名对象,特点:当前行运行结束后会立即调用它的析构函数结束对象的生命

	// Person(p3);
	// 注意:2、不要利用匿名实例化对象调用拷贝构造。
	// 编译器会认为这是个对象的声明 Person(p3) === Person p3;
	// 编译器就会报语法错误,p3重定义


	// 3.隐式转换法
	Person p6 = 10; // 相当于 Person p6 = Person(10);
	Person p7 = p6; // 隐式法 调用 拷贝构造

}

class ccopy {
public:
	int age;
public:
	ccopy() {

	}
	ccopy(int age) {
		this->age = age;
	}
	ccopy(const ccopy & c) {
		this->age = c.age + 1;  // 这样写测试更明显
	}

	~ccopy() {
	}

};

void dowork(ccopy p) {
	// 这里实参传入时会触发拷贝构造函数
	// 我们将拷贝构造函数修改为  新对象时旧对象的age+1;
	cout << "拷贝打印 " << p.age << endl; // 这里打印2 因为拷贝构造中 cc1.age+1 == 2

}
ccopy dowork2() {
	ccopy c(1);
	return c; // 这里函数结束后栈被释放,
			  //但是释放前拷贝了c对象,所以返回 通过触发拷贝构造 产生的对象
}
void text01() {
	// 拷贝函数的调用时机
	// 1.使用一个已经初始化完毕的对象来初始化一个新对象。
	ccopy c1(10);
	ccopy c2 = c1;

	// 2.值传递的方式给函数参数传值
	ccopy cc1(1);
	dowork(cc1); // 调用形参为ccopy对象的函数 传入的cc1 age==1;

	// 3.值方式返回局部对象
	ccopy cc2 = dowork2(); // 这里cc2.age == 2; 
						// 因为调用函数dowork2 时触发拷贝
					 // dowork2中实例化了c对象然后栈销毁前触发拷贝构造c.age+1 == 2
	cout << "cc2 == " << cc2.age << endl; // cc2 == 2
}


int main()
{
	text01();
	//fun f;

	
	return 0;
}

如果你写了拷贝构造函数,编译器将不会提供其他的构造函数

class demo {

public:
	demo(const demo& d) { // 只写拷贝构造
	
	}
};

void t_demo() {
	demo d; // 这里实例化不了demo对象。因为没有构造函数
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/836377.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号