C++拷贝构造函数介绍
2024-01-02 14:17:42
介绍
C++拷贝构造函数是一个特殊的成员函数,它用于创建类对象的一个副本(即深复制)。当一个新对象被创建并且其初始值来自同类的另一个对象时,拷贝构造函数会被自动调用。以下是拷贝构造函数的主要特点:
-
定义:
拷贝构造函数具有单个参数,该参数是对本类类型的引用,并且通常为const引用,以防止意外修改原对象。class MyClass { public: // 拷贝构造函数声明 MyClass(const MyClass& other); // 或者 MyClass(MyClass const &other); // ...其他成员变量和成员函数... };
-
调用时机:
- 当一个新对象通过现有对象进行初始化时。
- 当一个对象作为函数的参数以值传递时。
- 当一个对象从函数返回时(如果返回类型是对象而不是引用或指针)。
- 在某些STL容器(如vector、list等)中插入元素时。
-
行为:
拷贝构造函数负责正确地初始化新对象,这可能包括:- 复制所有数据成员的值。
- 如果类包含指针或其他资源(例如文件句柄、网络连接等),则需要分配新的资源并复制这些资源的内容,而非简单地复制指针。
- 调用基类的拷贝构造函数来复制基类部分的状态。
-
默认行为与自定义:
- 如果程序员没有显式提供拷贝构造函数,编译器将生成一个默认的拷贝构造函数,它会逐个成员地执行浅复制(对于指针,只复制指针本身而不复制指针指向的数据)。
- 对于包含动态内存分配、共享资源或其他需要特殊处理的情况,通常需要自定义拷贝构造函数来确保正确地管理资源。
-
常量引用参数:
参数通常使用const引用的原因是避免不必要的临时对象创建和销毁,同时表明不会更改传入的对象状态。虽然不强制要求const,但在实际编程实践中几乎总是选择const引用,以遵循最佳实践。
应用举例
#include <iostream>
#include <cstring> // 用于memcpy
class String {
public:
// 普通构造函数,初始化字符串
String(const char* str) : length(strlen(str)), content(new char[length + 1]) {
memcpy(content, str, length + 1); // 包括结束符'\0'
}
// 拷贝构造函数(深度拷贝)
String(const String& other) : length(other.length), content(new char[other.length + 1]) {
memcpy(content, other.content, length + 1);
}
// 析构函数,释放内存资源
~String() {
delete[] content;
}
// 省略了赋值运算符重载以简化示例,实际项目中也需要进行深拷贝
private:
int length;
char* content;
};
int main() {
String s1("Hello, World!");
String s2(s1); // 这里会调用拷贝构造函数进行深度拷贝
std::cout << s1.content << std::endl; // 输出 "Hello, World!"
std::cout << s2.content << std::endl; // 输出 "Hello, World!"
return 0;
}
实例说明
在上述例子中,String
类有一个指向动态分配的字符数组的指针成员 content
。默认的浅拷贝行为只会复制这个指针,而不是复制指针所指向的数据。因此,在使用默认的浅拷贝构造函数时,当源对象和副本对象都析构时,它们会试图删除同一块内存区域,导致未定义的行为。通过自定义拷贝构造函数,我们为 s2
分配新的内存,并将 s1
的内容复制到新内存中,这样 s1
和 s2
就各自拥有独立的字符串数据,实现了深度拷贝。
总结
在实现拷贝构造函数时,一定要注意是否存在指针,或者其它资源(不能通过简单赋值完成的),就需要对指针所指的空间进行数据复制,不能只是简单的复制指针复制的浅复制。
文章来源:https://blog.csdn.net/scy518/article/details/135333569
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!