如果定义以下这个类:
因此,以上的类定义等价于以下类定义:
class Empty { public: Empty() { ... } //default构造函数 Empty(const Empty& rhs) { ... } //copy构造函数 ~Empty() { ... } //析构函数 Empty& operator=(const Empty& rhs) { ... } //copy assignment操作符 };
如果在类中没有显式地声明一个拷贝构造函数,那么,编译器将会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的位拷贝。位拷贝又称浅拷贝。
默认Copy构造函数中如果成员变量是内置类型,则按bit拷贝,如果成员变量不是内置类型,调用成员变量所属类型的Copy构造函数。
如下自定义copy构造函数的例子:
#include<iostream> using namespace std; #include <stdio.h> class point { private: int m_x,m_y; public: point() { m_x = 0; m_y = 0; } point(int x, int y) { m_x = x; m_y = y; } point(const point& p) { m_x = p.m_x; m_y = p.m_y; cout<<"copy constructor is called!"<<endl; } static point reverse(const point& p) { point p1; p1.m_x = p.getY(); p1.m_y = p.getX(); return p1; } int getX() const { return m_x; } int getY() const { return m_y; } void print() { cout<<m_x<<" "<<m_y<<endl; } }; int main() { point p(1, 2); point p1(p); //initialize p1 with p point p2 = point::reverse(p1); p2.print(); return 0; }
point类定义了一个copy构造函数,在main函数中,首先生成一个对象p,这会调用带参构造函数,然后用p初始化p1,这会调用一次copy构造函数,然后又调用reverse,以p1为实参,将p1的m_x和m_y交换,返回一个point对象,结果赋值给p2,这会调用两次copy构造函数,第一次是在参数传递的时候,第二次是在返回对象的时候。运行结果如下图:
只有当生出的代码合法且有适当机会证明它有意义,编译器才会自动生成赋值构造函数,万一两个条件有一个不符合,编译器会拒绝为class生成operator=。以下情况:
a、如果类包括引用成员或者const成员,编译器拒绝生成Copy赋值操作符。
因为”C++不允许让reference改指向不同对象!”,引用的变量值一经初始化就不可以再修改其指向,同样const变量的值一经初始化就不可以再改变!
b、如果某个base classes将copy assignment操作符声明为private,编译器将拒绝为其derived classes生成一个copy assignment操作符。
因为编译器为derived classes所生成的copy assignment操作符想象中可以处理base class的内容,但它当然无法调用derived class无权调用的private成员函数。