类中默认的六个函数

本文详细解析了C++中的构造函数、析构函数、拷贝构造函数及赋值运算符的重载,阐述了它们的作用、特点及使用场景,特别强调了深拷贝与浅拷贝的区别。

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

C++三大特征 封装 继承 多态
封装
类中的三个访问限定符
     1.public 公有 任意位置
     2.private 私有 本类类中
     3.protected 保护 本类和子类
类中
     默认以inline处理
类外
     默认以普通的函数处理方式处理
this 类类型* const

构造函数

构造函数和类名相同
(1)作用:给类的实例化对象赋资源
(2)开辟内存、生成对象
(3)构造函数可重载
(4)构造函数不可手动调用、由系统调用
(5)构造函数为顺序构造

	CGoods(char* name, int amount, float price)
	{
		std::cout << this << " :CGoods::CGoods(char*,int,float)" << std::endl;
		mname = new char[strlen(name) + 1];
		strcpy(mname, name);
		mamount = amount;
		mprice = price;
	}

析构函数

(1)释放内存,销毁对象
(2)析构函数原型只有一个
(3)析构函数不可重载
(4)析构函数可手动调用、退化成普通函数的调用
(5)先构造后析构

	~CGoods()
	{
		std::cout << this << " :CGoods::~CGoods()" << std::endl;
		delete[] mname;
		mname = NULL;
	}

拷贝构造函数

用一个已经存在的对象来生成相同类型的新对象
     1.形参一定要是引用,否则会陷入无限递归
     2.默认的拷贝构造函数是浅拷贝
        类中有指针 考虑实现深拷贝

初始化和赋值的区别
初始化:创建一个新的对象,并且其初值来源于另一个已存在的对象。
int a; a=b;
赋值:在两个已经存在的对象间进行的。
int a=b;
赋值的时候调用重载的赋值运算符,初始化的时候调用拷贝构造函数。

CGoods good3 = good2;
CGoods(CGoods src) 是拷贝构造函数,用同类型已经存在的对象构造新对象
CGoods src = good2;(3)--> CGoods(CGoods src)
CGoods src = good2;(4)--> CGoods(CGoods src)

good3 的产生调用了 CGoods(CGoods src) 函数,函数的调用先压实参,good2 是实参,src 是形参,实参到形参是初始化的过程(3),good2 是一个已存在的对象,若想生成新的对象要调用拷贝构造函数,调用函数第一件事是构造形参(4)

	//CGoods good3 = good2;//初始化//系统默认使用拷贝构造函数
	//对象自己的成员,可以任意访问自己的其他任何访问限定成员方法和成员变量
	//CGoods(CGoods* const this, const CGoods &rhs)
	CGoods(const CGoods &rhs)
	{
		cout << &rhs << "->" << this <<endl;
		cout << "CGoods(const CGoods&)"<<endl;
		
		mname = new char[strlen(rhs.mname)+1];
		mamount = rhs.mamount;
		mprice = rhs.mprice;
	}

赋值运算符的重载函数

用一个已存在的对象来给另一个相同类型的已存在对象赋值
返回值是类类型的的引用,形参一定要用常引用
常引用作用:
1、防止实参被修改
2、接收隐士生成的临时对象

默认的赋值运算符的重载函数是浅拷贝
取地址操作符的重载函数
const 修饰的取地址操作符的重载函数

rhs 可以不加引用,用值传递,但是效率不高,因为会产生新的对象
不加引用时初始化的时候调用拷贝构造函数,产生新的 CGoods 对象
	void operator=(const CGoods &rhs)
	{
		cout << &rhs << "->" << this <<endl;
		cout << "operator=(const CGoods&)"<<endl;

		//防止自赋值
		if(this == &rhs)
		{
			return ;
		}
		//释放当前对象占用的其他资源
		delete []mname;
		mname = NULL;
		//开辟新资源
		mname = new char[strlen(rhs.mname)+1];
		strcpy(mname, rhs.mname);
		mamount = rhs.mamount;
		mprice = rhs.mprice;
	}

取地址操作符的重载函数

const 修饰的取地址操作符的重载函数

#include <iostream>

using namespace std;

class CGoods
{
public:
	CGoods()
	{
		std::cout << this << " :CGoods::CGoods()" << std::endl;
		mname = new char[1];
		mname = '\0';
		mamount = 0;
		mprice = 0.0;
	}
	CGoods(char* name, int amount, float price)
	{
		std::cout << this << " :CGoods::CGoods(char*,int,float)" << std::endl;
		mname = new char[strlen(name) + 1];
		strcpy(mname, name);
		mamount = amount;
		mprice = price;
	}
	//CGoods good3 = good2;
	//对象自己的成员,可以任意访问自己的其他任何访问限定成员方法和成员变量
	//CGoods(CGoods* const this, const CGoods &rhs)
	CGoods(const CGoods &rhs)
	{
		cout << &rhs << "->" << this <<endl;
		cout << "CGoods(const CGoods&)"<<endl;
		
		mname = new char[strlen(rhs.mname)+1];
		strcpy(mname, rhs.mname);
		mamount = rhs.mamount;
		mprice = rhs.mprice;
	}

	//可以不加引用,用值传递,但是效率不高,因为会产生新的对象
	//不加引用时初始化的时候调用拷贝构造函数,产生新的CGoods对象
	void operator=(const CGoods &rhs)
	{
		cout << &rhs << "->" << this <<endl;
		cout << "operator=(const CGoods&)"<<endl;

		//防止自赋值
		if(this == &rhs)
		{
			return ;
		}
		//释放当前对象占用的其他资源
		delete []mname;
		mname = NULL;
		mname = new char[strlen(rhs.mname)+1];
		strcpy(mname, rhs.mname);
		mamount = rhs.mamount;
		mprice = rhs.mprice;
	}
	~CGoods()
	{
		std::cout << this << " :CGoods::~CGoods()" << std::endl;
		delete[] mname;
		mname = NULL;
	}
	void show()
	{
		cout << "name:"<<mname<<endl;
		cout << "amount:"<<mamount<<endl;
		cout << "price:"<<mprice<<endl;
	}
private:
	char* mname;
	int mamount;
	float mprice;
};


int main()
{
	CGoods good1;
	CGoods good2("aaa",10,2.2);  
	CGoods good3 = good2;//初始化//系统默认使用拷贝构造函数
	
	//默认的赋值,没有产生新的对象 发生浅拷贝问题,内存泄漏
	//good.=(good3); good1调用'='传入good3
	//void operator=(const CGoods &rhs)

	good1 = good3;
}

class String
{
public:
	String();
	String(char* str);
	String(const String& rhs);
	String &operator=(const String&rhs);
	~String();
private:
	char* _str;
};

String::String()
{
	_str=new char[1];
}
String::String(char* str)
{
	int len=strlen(str);
	_str=new char[len+1];
	strcpy(_str,str);
}
String::String(const String& rhs)
{
	int len=strlen(rhs._str);
	_str=new char[len+1];
	strcpy(_str,rhs._str);
}
String &String::operator=(const String&rhs)
{
	if(this!=&rhs)
	{
		delete[] _str;
		_str=new char[strlen(rhs._str)+1];
		strcpy(_str,rhs._str);
	}
	return *this;
}
String::~String()
{
	delete[] _str;
	_str=NULL;
}```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值