在C++中,拷贝构造器(Copy Constructor)是一种特殊的构造函数,用于创建一个新对象,该对象是另一个同类型对象的副本。当使用一个已存在的对象来初始化一个新对象时,拷贝构造器会被调用。
拷贝构造器的定义
拷贝构造器的一般形式如下:
class ClassName {
public:// 拷贝构造器ClassName(const ClassName& other) {// 实现对象成员的拷贝}
};
- 参数:拷贝构造器接受一个同类型对象的常量引用作为参数。使用常量引用是为了避免不必要的对象复制,同时确保原始对象不会被修改。
- 函数名:拷贝构造器的函数名与类名相同。
调用拷贝构造器的场景
- 使用一个对象初始化另一个对象
#include <iostream>class Point {
private:int x;int y;
public:// 构造函数Point(int x = 0, int y = 0) : x(x), y(y) {}// 拷贝构造器Point(const Point& other) : x(other.x), y(other.y) {std::cout << "Copy constructor called" << std::endl;}void print() {std::cout << "x: " << x << ", y: " << y << std::endl;}
};int main() {Point p1(1, 2);Point p2(p1); // 调用拷贝构造器p2.print();return 0;
}
- 对象作为函数参数按值传递
#include <iostream>class Point {
private:int x;int y;
public:// 构造函数Point(int x = 0, int y = 0) : x(x), y(y) {}// 拷贝构造器Point(const Point& other) : x(other.x), y(other.y) {std::cout << "Copy constructor called" << std::endl;}void print() {std::cout << "x: " << x << ", y: " << y << std::endl;}
};void func(Point p) {p.print();
}int main() {Point p(1, 2);func(p); // 调用拷贝构造器return 0;
}
- 函数返回对象
#include <iostream>class Point {
private:int x;int y;
public:// 构造函数Point(int x = 0, int y = 0) : x(x), y(y) {}// 拷贝构造器Point(const Point& other) : x(other.x), y(other.y) {std::cout << "Copy constructor called" << std::endl;}void print() {std::cout << "x: " << x << ", y: " << y << std::endl;}
};Point createPoint() {Point p(1, 2);return p; // 调用拷贝构造器
}int main() {Point p = createPoint();p.print();return 0;
}
默认拷贝构造器
如果没有为类显式定义拷贝构造器,编译器会自动生成一个默认的拷贝构造器。默认拷贝构造器会执行浅拷贝,即逐个复制对象的成员变量。
浅拷贝和深拷贝
- 浅拷贝:默认拷贝构造器执行的是浅拷贝,它只是简单地复制对象的成员变量。如果对象包含指针成员,浅拷贝会导致两个对象的指针指向同一块内存,当其中一个对象被销毁时,另一个对象的指针会变成悬空指针。
- 深拷贝:深拷贝会为新对象分配独立的内存,并将原始对象的数据复制到新的内存中。当类包含动态分配的内存时,需要显式定义拷贝构造器来实现深拷贝。
#include <iostream>
#include <cstring>class MyString {
private:char* str;
public:// 构造函数MyString(const char* s = "") {if (s == nullptr) {str = new char[1];str[0] = '\0';} else {str = new char[strlen(s) + 1];strcpy(str, s);}}// 拷贝构造器(深拷贝)MyString(const MyString& other) {str = new char[strlen(other.str) + 1];strcpy(str, other.str);std::cout << "Deep copy constructor called" << std::endl;}// 析构函数~MyString() {delete[] str;}void print() {std::cout << str << std::endl;}
};int main() {MyString s1("Hello");MyString s2(s1); // 调用深拷贝构造器s2.print();return 0;
}
在这个例子中,MyString
类的拷贝构造器实现了深拷贝,为新对象分配了独立的内存,并将原始对象的字符串复制到新的内存中。这样,当一个对象被销毁时,不会影响另一个对象。