第三章 类
第五节 拷贝构造函数
-
默认情况下,类对象的拷贝是每个成员变量逐个拷贝
-
如果一个类的构造函数的第一个参数,是所属类类型的引用,如果还有其他额外参数,那么这个额外的参数都有默认值,
则这个构造函数就叫做拷贝构造函数,函数默认参数必须放在函数声明中,除非该函数没有函数声明 -
拷贝构造函数:会在一定的时机,被系统自动调用
-
拷贝构造函数又叫做复制构造函数
1. 拷贝构造函数
-
建议拷贝构造函数第一个参数总是带着const
-
拷贝构造函数一般不要声明成explicit
-
成员变量逐个拷贝的功能因为我们自己定义的拷贝构造函数的存在而丢失了作用,或者说我们自己的"拷贝构造函数"
取代了系统默认的每个成员变量逐个拷贝的这种行为
-
如果没有为类定义一个拷贝构造函数,编译器就会帮我们定义一个"合成拷贝构造函数"
-
如果是编译器给我们合成的拷贝构造函数,这个合成拷贝构造函数一般也是将类中的成员逐个拷贝到正在创建的对象中
每个成员的类型决定其拷贝方式,如果成员变量是整型,就直接把值拷贝过来,如果成员变量是类类型,那么就会调用这个类的拷贝构造函数 -
如果自己定义了拷贝构造函数,那么就取代了系统合成的拷贝构造函数,这个时候,就必须要在自己的拷贝构造函数中给类成员赋值,以免出现类成员没有被赋值就使用的情况发生
还有一些情况会发生拷贝构造函数的情形
-
将一个对象作为实参传给一个非引用类型的的形参
-
从一个函数中返回一个对象的时候会调用拷贝构造函数(windows会,linux不会?),LZ做实验并不会啊,
查看地址发现返回的地址是和函数中临时变量的地址相同,所以没有调用拷贝构造函数 -
time.h
//
// Created by felaim on 2020/5/26.
//
#ifndef LESSION_PART_TWO_TIME_H
#define LESSION_PART_TWO_TIME_H
class Tmpclass {
public:
Tmpclass() {
std::cout << "执行了构造函数 Tmpclass()" << std::endl;
}
Tmpclass(Tmpclass &tmpclass) {
std::cout << "执行了拷贝构造函数 Tmpclass(Tmpclass &tmpclass)" << std::endl;
}
};
class Time2 {
public:
Time2();
// 拷贝构造函数
Time2(const Time2 &temtime);
// Tmpclass cl;
public:
int Hour;
int Minute;
int Second{0};
};
#endif //LESSION_PART_TWO_TIME_H
- time.cpp
//
// Created by felaim on 2020/5/26.
//
#include <iostream>
#include "Time.h"
Time2::Time2() {
Hour = 12;
Minute = 59;
Second = 59;
std::cout << "执行了构造函数Time2::Time2()" << std::endl;
}
Time2::Time2(const Time2 &temptime) {
std::cout << "执行了拷贝构造函数Time2::Time2(Time2 &temtime, int a)" << std::endl;
Hour = temptime.Hour;
Minute = temptime.Minute;
Second = temptime.Second;
}
- main.cpp
#include <iostream>
#include "Time.h"
using namespace std;
void func(Time2 tmptime) {
return;
}
Time2 func2() {
Time2 tmp;
return tmp;
}
int main() {
//生成对象时,会调用类的构造函数的
Time2 mytime;
cout << "mytime: " << mytime.Hour << ":" << mytime.Minute << ":" << mytime.Second << endl;
//调用了拷贝构造函数
// Time2 mytime1 = mytime;
// Time2 mytime2(mytime);
// Time2 mytime3{mytime};
// Time2 mytime4 = {mytime};
// Time2 mytime5;
// mytime5 = mytime;
//调用了拷贝构造函数
// func(mytime);
//经测试,在linux下并没有调用拷贝构造函数
Time2 res = func2();
return 0;
}