关于拷贝构造函数、移动构造函数的例子

根据 https://blog.youkuaiyun.com/wkd_007/article/details/139633287 例子修改的

// g++ 14_Copy_Date.cpp -std=c++11
#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

#define MAX_NEW_MEM		(64*1000*1000)

class CDate
{
public:
	CDate(int year, int mon, int day);	// 构造函数声明
	CDate(const CDate& date);			// 拷贝构造函数声明
	~CDate();							// 析构函数声明
	
	CDate operator+(int day);			// 加号运算符声明
    CDate(CDate&& date);
	void show()
	{
		cout << "Date: " << m_year << "." << m_mon << "." << m_day << ", this=" << this << endl;
		//cout << "Date: " << str << endl;
	}

private:
	int m_year;
	int m_mon;
	int m_day;
	char *str;
};

// 构造函数定义
CDate::CDate(int year, int mon, int day)
{
	m_year = year;
	m_mon = mon;
	m_day = day;
	str = new char[MAX_NEW_MEM];
	sprintf(str, "%4d.%02d.%02d", year,mon,day);
	cout << "Calling Constructor" << ", this=" << this << endl;
}

// 拷贝构造函数定义
CDate::CDate(const CDate& date) // 不加const cannot bind non-const lvalue reference of type 'CDate&' to an rvalue of type 'std::remove_reference<CDate>::type' {aka 'CDate'}
{
	m_year = date.m_year;
	m_mon = date.m_mon;
	m_day = date.m_day;
	str = new char[MAX_NEW_MEM];
	memcpy(str, date.str, MAX_NEW_MEM);
    // str = date.str;
    // date.str = NULL;
	cout << "Calling Copy Constructor" << ", this=" << this << ", Copy Data=" << &date <<endl;
}

CDate::CDate(CDate&& date)
{
	m_year = date.m_year;
	m_mon = date.m_mon;
	m_day = date.m_day;
	str = date.str;
    date.str = NULL;
	cout << "Calling Move Copy Constructor" << ", this=" << this << ", Copy Data=" << &date <<endl;
}

// 析构函数定义
CDate::~CDate()
{
	cout << "Calling Destructor" << ", this=" << this <<endl;
	delete [] str;
}

CDate CDate::operator+(int day)
{
	CDate temp = *this;
	temp.m_day += day;
	cout << "Calling operator+" << ", this=" << this << ", tmp=" << &temp << endl;
	return temp;
}

int main()
{
	CDate date(2024,06,07);
	cout << endl;
	cout << "date=" << &date <<endl;
    CDate date1 = std::move(date+1);// std::move 强制将 date+1 的求值结果转为右值
    /*
		Calling Constructor, this=0x61fd00

		date=0x61fd00
		Calling Copy Constructor, this=0x61fb40, Copy Data=0x61fd00
		Calling operator+, this=0x61fd00, tmp=0x61fb40
		Calling Move Copy Constructor, this=0x61fd20, Copy Data=0x61fb40  // temp 赋值给临时(匿名)对象,走的移动构造函数
		Calling Destructor, this=0x61fb40
		Calling Move Copy Constructor, this=0x61fce0, Copy Data=0x61fd20  // 临时(匿名)对象赋值给date1,走的移动构造函数
		Calling Destructor, this=0x61fd20
		date1=0x61fce0
    */
	/*  把移动构造函数&&注掉,发现对象生成的个数没有变,该生成几个还是几个。变的是&&构造函数里面,对str,不需要再new了。相当于直接用已经new的str
	    而&的构造函数里面,入参不加const,如果直接CDate date1(date)不会报错,如果是CDate date1(date+1)会报错,
		cannot bind non-const lvalue reference of type 'CDate&' to an rvalue of type 'std::remove_reference<CDate>::type' {aka 'CDate'}
		应该是不允许不加const,然后赋个右值(operator+返回的匿名对象)。加了const,不能改值,相当于右值? 可能是因为右值不能取地址,不能修改右值,所以要加const
		Calling Constructor, this=0x61fd00

		date=0x61fd00
		Calling Copy Constructor, this=0x61fb40, Copy Data=0x61fd00
		Calling operator+, this=0x61fd00, tmp=0x61fb40
		Calling Copy Constructor, this=0x61fd20, Copy Data=0x61fb40
		Calling Destructor, this=0x61fb40
		Calling Copy Constructor, this=0x61fce0, Copy Data=0x61fd20
		Calling Destructor, this=0x61fd20
		date1=0x61fce0
	*/

	// CDate date1(date);
    /*
		Calling Constructor, this=0x61fd00

		date=0x61fd00
		Calling Copy Constructor, this=0x61fb40, Copy Data=0x61fd00
		Calling operator+, this=0x61fd00, tmp=0x61fb40
		Calling Move Copy Constructor, this=0x61fd20, Copy Data=0x61fb40
		Calling Destructor, this=0x61fb40
		Calling Move Copy Constructor, this=0x61fce0, Copy Data=0x61fd20
		Calling Destructor, this=0x61fd20
		date1=0x61fce0
    */
   	//CDate date1 = std::move(date);
	cout << "date1=" << &date1 <<endl;
	date1.show();
	
	cout << endl;
	int a = 0;
	int b = 1;
	cout<< typeid((a==b) + 1).name() << " " << typeid((a==b + 1)).name() << endl;
	
	return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值