复制构造函数
参考链接:
http://c.biancheng.net/view/151.html
1. 简介
也叫拷贝构造函数,构造函数的一种,只有一个参数,参数类型是本类的引用。
如果不写复制构造函数,编译器就会自动生成复制构造函数(默认复制构造函数)。
2. 举例
2.1 默认复制构造
#include <iostream>
class A
{
public:
int x , y;
A( int x,int y) : x(x),y(y)
{
}
};
int main(int argc, char const *argv[])
{
A a1(1,2);
// 调用默认的拷贝构造
A a2(a1);
std::cout << "a1.x: "<<a1. x << " a1.y: "<<a1. y <<std:: endl;
std::cout << "a2.x: "<<a2. x << " a2.y: "<<a2. y <<std:: endl;
return 0;
}
运行结果:
2.2 重写复制构造
#include <iostream>
class A
{
public:
int x , y;
A( int x,int y) : x(x),y(y){}
A( A& a)
{
x = a.x;
y = a.y;
std::cout << " copy Constructor no const" << std::endl;
}
A(const A& a)
{
// a对象中的x,y值没有拷贝到A对象中
std::cout << " copy Constructor have const" << std::endl;
}
};
int main(int argc, char const *argv[])
{
A a1(1,2);
const A a2(3,4);
// 拷贝构造
// a1 拷贝到 a3, a1 无const修饰
A a3(a1);
// a2 拷贝到 a4, a2 有const修饰
A a4(a2);
std::cout << "a3.x: "<<a3. x << " a3.y: "<<a3. y <<std:: endl;
std::cout << "a4.x: "<<a4. x << " a4.y: "<<a4. y <<std:: endl;
return 0;
}
结果:
3. 复制构造函数被调用的三种情况
3.1 当用一个对象去初始化同类的另一个对象时
以上面的代码举例:
A a1(1,2);
A a2(a1);
//等同于
A a2 = a1;
初始化和赋值:
// 初始化
int x = 0;
// 赋值 将y的值赋给x
int x;
int y;
x = y;
3.2 类A的对象作为函数的参数,当调用函数时
#include <iostream>
class A
{
public:
int x , y;
A( int x,int y) : x(x),y(y)
{
}
A( A& a)
{
x = a.x;
y = a.y;
std::cout << " copy Constructor " << std::endl;
}
};
void Fun(A a){}
int main(int argc, char const *argv[])
{
A a(1,2);
Fun(a);
return 0;
}
// 输出结果: copy Constructor
3.3 如果函数的返回值是类 A 的对象,则函数返回时,类 A 的复制构造函数被调用
#include <iostream>
class A
{
public:
int x , y;
A( int x,int y) : x(x),y(y)
{
}
A(const A& a)
{
x = a.x;
y = a.y;
std::cout << " copy Constructor " << std::endl;
}
};
A Fun()
{
A a(1,2);
return a;
}
int main(int argc, char const *argv[])
{
std::cout<< Fun().x<<std:: endl;
return 0;
}
结果输出为:1 并未打印复制构造函数中的输出语句
将Fun()中的a设为全局:
#include <iostream>
class A
{
public:
int x , y;
A( int x,int y) : x(x),y(y)
{
}
A(const A& a)
{
x = a.x;
y = a.y;
std::cout << " copy Constructor " << std::endl;
}
A operator=(A& a)
{
x = a.x;
y = a.y;
std::cout << " copy Constructor " << std::endl;
return *this;
}
};
A a(1,2);
A Fun()
{
return a;
}
int main(int argc, char const *argv[])
{
std::cout<< Fun().x<<std:: endl;
return 0;
}
结果输出为:
有些编译器出于程序执行效率的考虑,编译的时候进行了优化,函数返回值对象就不用复制构造函数初始化了,这并不符合 C++ 的标准。对这一点,读者不必深究。
4. 自定义String类
#include <iostream>
#include <string.h>
// 自定义字符串类
class String
{
private:
// 字符
char * m_Buffer;
// 字符长度
unsigned int m_Size;
public:
// 构造函数
String(const char * string)
{
m_Size = strlen(string);
m_Buffer = new char[m_Size+1];
memcpy(m_Buffer,string,m_Size);
m_Buffer[m_Size] = 0;
}
// 拷贝构造函数
String(const String& str)
: m_Size(str.m_Size)
{
std :: cout << " copy String "<< std ::endl;
m_Buffer = new char[m_Size + 1];
memcpy(m_Buffer, str.m_Buffer, m_Size+1);
}
// 析构函数 在对象销毁时自动调用
~String()
{
delete[] m_Buffer;
}
// 操作符重载
char& operator[](unsigned int index)
{
std :: cout << "--- [] ---" << std ::endl;
return m_Buffer[index];
}
friend std::ostream& operator << (std::ostream& stream, const String& string);
};
// 重载左移操作符
// 输出自定义字符串
std::ostream& operator << (std::ostream& stream, const String& string)
{
std :: cout << "--- << ---" << std ::endl;
stream << string.m_Buffer;
return stream;
}
int main(int argc, char const *argv[])
{
String one = "The Chinese don't lie to the Chinese";
std :: cout << "---1---" << std ::endl;
String two = one;
std :: cout << "---2---" << std ::endl;
two[2] = 'a';
std :: cout << "---3---" << std ::endl;
std :: cout << one << std ::endl;
std :: cout << "---4---" << std ::endl;
std :: cout << two << std ::endl;
std :: cout << "---5---" << std ::endl;
return 0;
}
输出结果
5. 复制构造函数学习参考链接:
https://www.bilibili.com/video/BV13T4y1P7tw?spm_id_from=333.999.0.0
6. 运算符及重载学习参考链接:
https://www.bilibili.com/video/BV17X4y1M7Vb?spm_id_from=333.999.0.0