23 构造和析构函数

构造函数

1 C++的类可以定义与类名相同的特殊函数,这种与类名相同的函数叫做构造函数

2 构造函数在定义时可以有参数

3 没有返回类型声明

析构函数

特殊的成员函数清理对象,析构函数

语法:~className()

析构函数没有参数,没有返回类型声明

析构函数在对象销毁时自动被调用

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class Test {
public:
	// 无参数 构造函数
	Test() {
		a = 10;		// 完成对属性的初始化
		p = (char*)malloc(100);
		strcpy(p, "abcdefg");
		cout << "构造函数" << endl;
	}

	void printP() {
		cout << p << endl;
		cout << a << endl;
	}

	// 析构时先创建时后释放
	~Test() {
		if (p != NULL) {
			free(p);
		}
		cout << "析构函数" << endl;
	}

private:
	int a;
	char* p;

};

void objplay() {
	Test t1;
	t1.printP();

	cout << "-------------" << endl;

	Test t2;
	t2.printP();
}

int main() {
	objplay();
	return 0;
}

构造函数的三种调用方法

1 括号法

2 等号法

3 直接法

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class Test {
public:
	// 无参数 构造函数
	Test() {
		cout << "无参构造函数" << endl;
	}

	Test(int a) {
		m_a = a;
		m_b = 0;
	}

	Test(int a, int b) {
		m_a = a;
		m_b = b;
		cout << "有参构造函数" << endl;
	}

	//赋值构造函数
	Test(const Test& obj) {
		cout << "赋值、拷贝构造函数" << endl;
	}

	void printT() {
		cout << "普通成员函数" << endl;
	}

private:
	int m_a;
	int m_b;

	/*int a;
	char* p;*/

};

int main() {
	// Test t1;	// 调用无参数构造函数

	Test t1(1, 2);	// 调用有参构造函数(括号法) c++编译器调用
	t1.printT();
	cout << "-------------" << endl;

	Test t2 = (3, 4);	//逗号表达式,最后一个值 4(等号法) c++编译器调用
	Test t3 = 5;

	Test t4 = Test(1, 2);	// 手动调用 产生一个匿名对象(匿名对象的去留问题)  t4对象初始化
    
    // 对象初始化和对象的赋值
    t1 = t4; // 把t4拷贝给t1 赋值操作

	return 0;
}

初始化用途

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class Test {
public:
	void init(int _a, int _b) {
		a = _a;
		b = _b;
	}

private:
	int a;
	int b;
};

void main() {
	// 类没有提供构造函数,c++编译器会自动提供一个默认的构造函数
	// 类没有提供构造函数 拷贝构造函数, C++编译器会自动给程序员提供一个默认的拷贝构造函数
	Test t1;
	int a = 10;
	int b = 20;
	t1.init(a, b);

	Test t21;	t21.init(1, 2);
	Test t22;	t22.init(1, 2);
	Test t23;	t23.init(1, 2);

	// 这种场景下,显式初始化难以使用
	Test tArray[3] = { t21, t22, t23 };

	/*Test tArray[3];
	tArray[0].init(1, 2);
	tArray[1].init(1, 2);
	tArray[2].init(1, 2);*/


}

赋值(copy)构造函数四种调用时机

用一个对象初始化另外一个对象

第一种方法

class Test {
public:
	// 无参数 构造函数
	Test() {
		cout << "无参构造函数" << endl;
	}

	Test(int a) {
		m_a = a;
		m_b = 0;
	}

	Test(int a, int b) {
		m_a = a;
		m_b = b;
		cout << "有参构造函数" << endl;
	}

	//赋值构造函数
	Test(const Test& obj) {
		cout << "赋值、拷贝构造函数" << endl;
		m_a = obj.m_a + 100;	// 可以更改拷贝构造
		m_b = obj.m_b + 100;
	}

	void printT() {
		cout << "普通成员函数" << endl;
		cout << "m_a" << m_a << endl;
		cout << "m_b" << m_b << endl;
	}

private:
	int m_a;
	int m_b;

	/*int a;
	char* p;*/

};

int main() {
	Test t0(1, 2);
	Test t1(1, 2);	

	t0 = t1;	//用t1给t0赋值 赋值和初始化是两个不同的概念
	// 第一种拷贝构造调用方法
	Test t2 = t1; // 用t1初始化t2
	t2.printT();
	
}

第二种拷贝构造调用方法

int main() {
	Test t0(1, 2);
	Test t1(1, 2);	

	t0 = t1;	//用t1给t0赋值 赋值和初始化是两个不同的概念
	//第二种拷贝构造调用方法
	Test t2(t1);	// 用t1初始化t2
	t2.printT();
}

第三种拷贝构造函数调用方法(函数形参)

// copy 构造函数
class Location {
public:
	Location(int xx = 0, int yy = 0) {
		X = xx;
		Y = yy;
		cout << "构造函数" << endl;
	}

	// copy构造函数 完成对象初始化
	Location(const Location& obj) {
		X = obj.X;
		Y = obj.Y;
	}

	~Location() {
		cout << X << "," << Y << "析构函数" << endl;
	}

	int GetX() { return X; }
	int GetY() { return Y; }
private:
	int X;
	int Y;
};

// 形参是元素
void f(Location p) {
	cout << p.GetX() << endl;
}

void printobj() {
	Location a(1, 2);
	Location b = a;
	cout << "b对象已经初始化完毕" << endl;

	f(b); // b实参初始化形参p,调用copy构造函数
}

void main() {
	printobj();
}

第四种拷贝构造函数调用方式

class Location {
public:
	Location(int xx = 0, int yy = 0) {
		X = xx;
		Y = yy;
		cout << "构造函数" << endl;
	}

	// copy构造函数 完成对象初始化
	Location(const Location& obj) {
		X = obj.X;
		Y = obj.Y;
	}

	~Location() {
		cout << X << "," << Y << "析构函数" << endl;
	}

	int GetX() { return X; }
	int GetY() { return Y; }
private:
	int X;
	int Y;
};

// 形参是元素
void f(Location p) {
	cout << p.GetX() << endl;
}


// g函数返回一个元素
// 函数的返回值是一个元素(复杂类型的) 返回的是一个新的匿名对象 调用匿名对象类的copy构造函数
// 默认返回一个新对象(匿名对象)
// 如果匿名对象初始化给另外一个同类型的对象,匿名对象转化为有名对象
// 如果匿名对象赋值给另外一个同类型的对象,匿名对象被析构
Location g() {
	Location A(1, 2);	// 调用一般构造函数
	return A;			// 调用copy构造函数 生成匿名对象
    // 最终两个对象都被析构(一共两次)
}

void playobj() {
	g();
}

void playobj2() {
	// 用匿名对象初始化m 此时c++编译器直接把匿名对象转为m
	Location m = g();
	cout << "匿名对象不会被析构" << endl;
	cout << m.GetX() << endl;
}

void playobj3() {
    // 匿名对象赋值给m2后,匿名对象被析构
	Location m2(1, 2);
	m2 = g();
	cout << "匿名对象赋值给m2 匿名对象被析构" << endl;// 匿名对象赋值给m2 匿名对象被析构
	cout << m2.GetX() << endl;
}

void main() {
	playobj3();
	//playobj2();
	//printobj();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值