一:拷贝构造函数
//普通的拷贝行为(比较简单)
int a=10;
int b=a;
二:拷贝构造函数的定义:
如果一个类的构造函数的第一个参数是所属类的引用,如果还有其它额外的参数,那么这些额外的参数必须又默认值,则这样的构造函数叫拷贝构造函数。
函数默认参数必须放在函数声明中,除非该函数没有函数声明。
例如:
class A
{
public:
A(const A &temp);//A(const A &temp,int a=10)
A():a1(2)
{
std::cout << "调用了A():a1(2)" << std::endl;
}
public:
int a1;
};
类外定义时,不需要指定形参默认值。
A::A(const A &temp,int a)
{
std::cout << "调用了A(const A &temp)" << std::endl;
}
三:
拷贝构造函数的作用:会在一定的时机被系统调用。
class T
{
public:
T():a(2),b(3)
{
std::cout << "调用了T()" << std::endl;
}
T(const T &temp)//T(const T &temp,int a=10)
{
std::cout << "调用了T(const T &temp)" << std::endl;
}
public:
int a;
int b;
};
例如:
T t1;//除了这个
T t2 = t1;
T t3 = { t1 };
T t4 (t1);
T t5 { t1 };
拷贝构造函数的使用建议:
拷贝构造函数的第一个参数一般都是带着const
拷贝构造函数一般不要声明成explicit(系统调用拷贝构造函数时一般都会进行隐式类型转换)、
例如:
A(const A &temp);
//不建议这样
explicit T(const T &temp)//T(const T &temp,int a=10)
{
std::cout << "调用了T(const T &temp)" << std::endl;
}
T t1;
T t2 = t1; //不可以
T t3 = { t1 };//不可以
T t4 (t1);
T t5 { t1 };
其它:
(1)默认情况下,类对象的拷贝是每个成员变量的逐个拷贝(内部实现机制比较复杂)。
(2)默认情况下,如果我们不定义拷贝构造函数,那么编译器会为我们定义一个默认拷贝构造函数
这个默认构造函数会为正在创建的对象的每个成员进行逐个拷贝,例如,如果类成员时int类型,
那么就进行值的拷贝,如果成员是一个类对象,而这个类对象成员的拷贝由它自己是否有拷贝
构造函数决定,如果有,那当然就有拷贝构造函数进行拷贝控制了,如果没有,拷贝动作就由
系统创建的合成默认构造函数决定
其它会调用拷贝构造函数的情况:
void fun(A a)
{
return;
}
A func()
{
A a;
return a;
}
调用fun函数和func函数时,会调用拷贝构造函数。
理解:func,因为return a时,返回的是一个临时对象,这个临时对象是通过这个局部对象a进行赋值的,所以这里会调用拷贝构造函数。
完整测试代码:
// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <iostream>
class A
{
public:
A(const A &temp)
{
std::cout << "调用了A(const A &temp)" << std::endl;
}
A():a1(2)
{
std::cout << "调用了A():a1(2)" << std::endl;
}
public:
int a1;
};
class T
{
public:
T():a(2),b(3)
{
std::cout << "调用了T()" << std::endl;
}
explicit T(const T &temp)//T(const T &temp,int a=10)
{
std::cout << "调用了T(const T &temp)" << std::endl;
}
public:
int a;
int b;
A obj;
};
void fun(A a)
{
return;
}
A func()
{
A a;
return a;
}
int main()
{
/*
一:拷贝构造函数
//普通的拷贝行为(比较简单)
int a=10;
int b=a;
拷贝构造函数的定义:
如果一个类的构造函数的第一个参数是所属类的引用,如果还有其它额外的参数,
那么这些额外的参数必须又默认值,则这样的构造函数叫拷贝构造函数。
函数默认参数必须放在函数声明中,除非该函数没有函数声明。
拷贝构造函数的作用:会在一定的时机被系统调用。
拷贝构造函数的使用建议:
拷贝构造函数的第一个参数一般都是带着const
拷贝构造函数一般不要声明成explicit(系统调用拷贝构造函数时一般都会进行隐式类型转换)
其它:
(1)默认情况下,类对象的拷贝是每个成员变量的逐个拷贝(内部实现机制比较复杂)。
(2)默认情况下,如果我们不定义拷贝构造函数,那么编译器会为我们定义一个默认拷贝构造函数
这个默认构造函数会为正在创建的对象的每个成员进行逐个拷贝,例如,如果类成员时int类型,
那么就进行值的拷贝,如果成员是一个类对象,而这个类对象成员的拷贝由它自己是否有拷贝
构造函数决定,如果有,那当然就有拷贝构造函数进行拷贝控制了,如果没有,拷贝动作就由
系统创建的合成默认构造函数决定
(3)自己定义的拷贝构造函数和系统合成的拷贝构造函数的区别
(4)其它会调用拷贝构造函数的情况
*/
T t1;
T t2 = t1;
T t3 = { t1 };
T t4 (t1);
T t5 { t1 };
A obj;
fun(obj);
return 0;
}