拷贝构造函数
默认情况下,类对象的拷贝是每个成员变量逐个拷贝;
含义:首先是一个类的构造函数,第一个参数是所属的类类型的引用,如果还有其他额外参数,那么这些额外参数必须都有默认值,函数默认参数必须放在函数声明,除非该函数没有函数声明;
作用:需要调用的时候,系统自动调用
建议:
- 拷贝构造函数第一个参数总是带const;
- explicit:拷贝构造函数一般不要声明成explicit;
成员变量逐个拷贝,由于定义了拷贝构造函数而丢失了作用,或者说自己定义的拷贝构造函数取代了系统默认的每个成员变量逐个拷贝的这种行为;
- 如果没有定义拷贝构造函数,编译器就会帮忙定义一个“合成拷贝构造函数”;
- 如果是编译器定义的合成构造拷贝函数,这个合成拷贝构造函数一般也是将参数的成员逐个拷贝到目标对象中;每个成员的类型决定它如何拷贝,如果成员变量是基本类型,就直接把值拷贝过来;如果成员变量是类类型,那么就会调用这个类的拷贝构造函数;
- 如果自己定义了拷贝构造函数,就取代了系统合成的拷贝构造函数,这时候,必须要在自己的拷贝构造函数中给类成员赋值以免类成员没有被赋值;
#include <iostream>
using namespace std;
//类定义(类声明)
class Time
{
public:
int Hour; //小时
int Minue; //分钟
int Second = 0; //秒钟
public:
//构造函数
Time();
//...
//拷贝构造函数
Time(Time &tmptime, int a = 1);
private:
//...
};
Time::Time()
{
std::cout<<"Time::Time()"<<std::endl;
}
Time::Time(Time &tmptime, int a):Hour(tmptime.Hour), Minue(tmptime.Minue), Second(tmptime.Second)
{
std::cout<<"Time::Time(Time &tmptime, int a)"<<std::endl;
}
int main()
{
Time myTime; //调用默认构造函数,不带参数的
Time mytime2 = myTime; //调用了拷贝构造函数
Time mytime3(myTime); //调用了拷贝构造函数
Time mytime4{myTime}; //调用了拷贝构造函数
Time mytime5 = {myTime}; //调用了拷贝构造函数
Time mytime6; //调用了无参构造函数
mytime6 = mytime5; //若类中有常量成员,则不成功
return 0;
}
其它调用拷贝构造函数的情况
调用拷贝构造的情况
-
将一个对象作为实参传递给一个非引用类型的形参也会调用了拷贝构造函数;
#include <iostream> using namespace std; //类定义(类声明) class Time { public: int Hour; //小时 int Minue; //分钟 int Second = 0; //秒钟 public: //构造函数 Time(); //... //拷贝构造函数 Time(Time &tmptime, int a = 1); private: //... }; Time::Time() { std::cout<<"Time::Time()"<<std::endl; } Time::Time(Time &tmptime, int a):Hour(tmptime.Hour), Minue(tmptime.Minue), Second(tmptime.Second) { std::cout<<"Time::Time(Time &tmptime, int a)"<<std::endl; } void func(Time tmpTime) { return; } int main() { Time myTime; func(myTime); return 0; }
-
函数中返回对象
#include <iostream> using namespace std; //类定义(类声明) class Time { public: int Hour = 0; //小时 int Minue = 0; //分钟 int Second = 0; //秒钟 public: //构造函数 Time(); //... //拷贝构造函数 Time(const Time& tmptime); private: //... }; Time::Time() { std::cout << "Time::Time()" << std::endl; } Time::Time(const Time& tmptime) :Hour(tmptime.Hour), Minue(tmptime.Minue), Second(tmptime.Second) { std::cout << "Time::Time(Time &tmptime, int a)" << std::endl; } Time func() { Time tmpTime; return tmpTime; //系统产生了临时对象,调用拷贝构造函数 } int main() { Time mytime = func(); //Time myTime; //Time myTime2 = myTime; return 0; }
名称 | 值 | 类型 | |
---|---|---|---|
◢ | &tmpTime | 0x000000487591fa68 | Time * |
名称 | 值 | 类型 | |
---|---|---|---|
◢ | &mytime | 0x000000487591fb98 | Time * |
二者地址都不一样,在返回对象的时候,系统会一个临时对象;
原文链接: https://www.cnblogs.com/NaughtyCoder/p/13324520.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;
也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/366909
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!