C++的copy构造函数

copy构造函数也被称为赋值构造函数

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

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

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

	//赋值构造函数 (copy构造函数) //
	Test(const Test& obj )
	{
		cout<<"我也是构造函数 " <<endl;
		m_b = obj.m_b + 100;
		m_a = obj.m_a + 100;
	}

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

C++中的copy构造函数有4种调用场景:

    Test  t1(1, 2);
//第1种调用方法
	Test t2 = t1; //用t1来初始化 t2 
	t2.printT();
//第2种调用方法
	Test t2(t1);  //用t1对象 初始化 t2对象 
	t2.printT();
//第3种调用方法
	//业务函数  形参是一个元素
void f(Test p)
{
	cout<<p.GetX()<<endl;
}
f(t1); //t1实参取初始化形参p,会调用copy构造函数
//第4种调用方法
//g函数 返回一个元素 
//结论1 : 函数的返回值是一个元素 (复杂类型的), 
//返回的是一个新的匿名对象(所以会调用匿名对象类的copy构造函数)

//
//结论2: 有关 匿名对象的去和留
//如果用匿名对象  初始化 另外一个同类型的对象, 匿名对象 转成有名对象
//如果用匿名对象  赋值给 另外一个同类型的对象, 匿名对象 被析构

//
//你这么写代码,设计编译器的大牛们:
//我就给你返回一个新对象(没有名字 匿名对象)
Test g()
{
	Test A(1, 2);
	return A;
}
//
void objplay3()
{
	//用匿名对象初始化m 此时c++编译器 直接把匿名对转成m(扶正) 从匿名转成有名字了m
	Test m = g(); 
	printf("匿名对象,被扶正,不会析构掉\n");
	cout<<m.GetX()<<endl;;
}

void objplay4()
{
	//用匿名对象 赋值给 m2后, 匿名对象被析构
	Test m2(1, 2);
	m2 = g();
	printf("因为用匿名对象=给m2, 匿名对象,被析构\n");
	cout<<m2.GetX()<<endl;;
}

当类中定义了拷贝构造函数时,c++编译器不会提供无参数构造函数;当类中定义了有参数构造函数是,c++编译器不会提供无参数构造函数
如果类中的属性有指针,则会出现深拷贝和浅拷贝的问题

class  Name
{
public:
	Name(const char *myp)
	{
		m_len = strlen(myp);
		m_p =(char *) malloc(m_len + 1); //
		strcpy(m_p, myp);
	}
	~Name()
	{
		if (m_p != NULL)
		{
			free(m_p);
			m_p = NULL;
			m_len = 0;
		}
	}
protected:
private:
	char *m_p ;
	int m_len; 
};

//对象析构的时候 出现coredump
void objplaymain()
{
	Name obj1("abcdefg");
	//Name obj2 = obj1;  //C++编译器提供的 默认的copy构造函数  浅拷贝
	Name obj3("obj3");

	obj3 = obj1;  // C++编译器提供的 等号操作 也属 浅拷贝
}

上述代码在执行时,会出现浅拷贝问题
浅拷贝问题原因分析C++编译器在执行上述程序时,会使用编译器的默认拷贝构造函数,这个拷贝构造函数在执行时,会直接将obj1中指针的地址复制给obj2,而在执行西沟函数时,同一块内存空间被析构了两次,造成后面析构的指针变成了野指针,从而导致程序出错


	//Name obj2 = obj1;
	//解决方案: 手工的编写拷贝构造函数 使用深copy
	Name(const Name& obj1)
	{
		m_len = obj1.m_len;
		m_p = (char *)malloc(m_len + 1);
		strcpy(m_p, obj1.m_p);
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值