C++中的拷贝构造器(Copy Constructor)
在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
类的拷贝构造器实现了深拷贝,为新对象分配了独立的内存,并将原始对象的字符串复制到新的内存中。这样,当一个对象被销毁时,不会影响另一个对象。