关于c++拷贝构造函数及应用场景,const char[3] 转换为char * strcpy strcpy_s

 一:拷贝构造函数 

// panduan.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include<math.h>

using namespace std;
class test {
public:
	test(int x, int y)
	{
		m_x = x;
		m_y = y;
	}
	void print()
	{
		cout << "x=" << m_x << "   y=" << m_y << endl;
	}
	test()
	{
		    m_x = 0;
			m_y = 0;
	}
	//显示的拷构造函数
	test(const test &anther)//const只读,如果不提供,则会有默认的拷贝构造函数,将所有值进行拷贝
	{
		cout << "another " << endl;
		m_x = anther.m_x;
		m_y = anther.m_y;
	}
	//等号赋值操作符
	void operator=(const test &another)
	{
		m_x = anther.m_x;
		m_y = anther.m_y;
	}
private:
	int m_x;
	int m_y;
};

int main()
{
	test t1(100,200);
	//法一  用t1初始化t2
	test t2(t1);//用t1初始化t2,调用t2的拷贝构造函数
	t2.print();
	//法二 用t1初始化t3,构造函数是对象初始化时调用
	test t3;//调用t3的无参构造函数
	t3= t1;//没有调用t3的拷贝构造函数,而是用的t3的赋值操作符函数
	//法三
	test t4 = t1;//调用t4的拷贝构造函数
    return 0;
}

当没有显示的拷贝构造函数时,默认的拷贝构造函数就会出现

显示的有参构造函数也不会隐藏默认拷贝构造函数

没有显示的析构函数的时候,默认的析构函数就会出现

析构函数调用的顺序与构造相反,谁先构造的,谁后调用

二:深拷贝与浅拷贝

(1)遇到的错误1(我的编译器为vs2017)

      使用strcpy_s出现错误“strcpy_s"实例类型参数为(char*,const char*)

      解决办法strcpy_s(m_name,20,name)//指明缓冲区长度,strcpy_s可以接受3个参数

     遇到的错误2,代码如下

teacher(int id, char *name)
	{
		m_id = id;
		int len = strlen(name);
		m_name = (char*)malloc(len + 1);
		strcpy_s(m_name,20,name);
	}

   报错:无法将参数从const char[3] 转换为char *

  解决办法:在传入的参数中加上const

 

teacher(int id,const char *name)
	{
		m_id = id;
		int len = strlen(name);
		m_name = (char*)malloc(len + 1);
		strcpy_s(m_name,20,name);
	}

 

// panduan.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include<math.h>

using namespace std;
class teacher{
public:
	teacher(int id,const char *name)
	{
		m_id = id;
		int len = strlen(name);
		m_name = (char*)malloc(len + 1);
		strcpy_s(m_name,20,name);
	}
	~teacher()
	{
		cout << "xigou" << endl;
		if (m_name != NULL)
		{
			free(m_name);
			m_name = NULL;
		}

	}
	void printff()
	{
		cout << "id=m_id" << "name="<<m_name << endl;
	}
private:
	int m_id;
	char *m_name;
};

int main()
{
	teacher t1(1,"22");
	t1.printff();
	teacher t2(t1);//调用了t2的默认拷贝构造函数 t2有指向name的指针,t1也有指向name的指针,先析构t2,导致name的内存不能使用了,t1就不能再使用这个空间了,这就是因为浅拷贝
    return 0;
}

    使用拷贝构造函数的场景

使用拷贝构造函数的场景
场景1
void test1()
{
	Test t1(10, 20);
	Test t2(t1);
}
场景2
void test2()
{
	Test t1(10, 20);
	Test t2;
	t2 = t1;//操作符
}
场景3
void func(Test t)//Test t=t1;//t的拷贝构造函数
{
	cout << "func beegin" << endl;
	printff();
	cout << "func end" << endl;
}
void test3()
{
	Test t1(10, 20);
	func(t1);

}
场景4
Test func2()//temp的周期与func2的周期一样,用普通Test来接收它,会触发拷贝构造函数,用一个匿名对象去等于temp,最终func2返回一个匿名对象,func2执行完后,temp被立刻析构了
//若写成Test & func2() 这样返回的是temp本身
{
	Test temp(10, 20);
	temp.pringff();
	return temp;
}//匿名的对象 = temp 匿名对象的拷贝构造
void test4()
{
	func2();//返回一个匿名对象,当一个函数返回一个匿名对象的时候,
	        //函数外部没有任何变量去接收它,这个匿名对象将不会再被使用,
	        //编译器会直接将这个匿名对象回收掉,而不是等待整个函数执行完再回收
}
场景5
void test5()
{
	Test t1 = func2();//给匿名对象起了名字 叫t1

}
场景6
void test6()
{
	Test t1;//t1已经初始化了 用t1的默认构造函数
	t1 = func2();//t1已经初始化了,所以func2返回的匿名对象不会再次转正,依然是匿名对象
	             //所以t1会调用等号操作符,t.operator=匿名对象,然后编译器会立刻回收匿名对象

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值