欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 明星 > C++对象构造、赋值、拷贝与析构详解

C++对象构造、赋值、拷贝与析构详解

2025/2/21 21:57:29 来源:https://blog.csdn.net/FHKHH/article/details/144190752  浏览:    关键词:C++对象构造、赋值、拷贝与析构详解

C++对象构造、赋值、拷贝与析构详解


1. 构造函数

构造函数是用于初始化对象的函数,在创建对象时自动调用。

特点
  1. 名称与类名相同,无返回值。
  2. 可以重载,允许多个构造函数。
  3. 可以有默认值,也可以无参数(默认构造函数)。
代码示例
class Test {
public:int x, y;// 默认构造函数Test() : x(0), y(0) {cout << "Default Constructor called" << endl;}// 带参数的构造函数Test(int a, int b) : x(a), y(b) {cout << "Parameterized Constructor called" << endl;}
};
int main() {Test t1;            // 调用默认构造函数Test t2(10, 20);    // 调用带参数的构造函数return 0;
}
输出
Default Constructor called
Parameterized Constructor called

2. 拷贝构造函数

用于通过一个已存在的对象创建一个新对象。

特点
  1. 默认的拷贝构造函数执行浅拷贝(简单复制数据成员的值)。
  2. 如果类包含指针或动态分配的资源,建议定义深拷贝
代码示例(深拷贝实现)
class Test {
private:int* data;public:// 带参数构造函数Test(int value) {data = new int(value);cout << "Constructor called for value: " << *data << endl;}// 拷贝构造函数Test(const Test& obj) {data = new int(*obj.data);  // 深拷贝cout << "Copy Constructor called" << endl;}// 析构函数~Test() {delete data;cout << "Destructor called" << endl;}
};
int main() {Test t1(10);        // 调用构造函数Test t2 = t1;       // 调用拷贝构造函数return 0;
}
输出
Constructor called for value: 10
Copy Constructor called
Destructor called
Destructor called

3. 赋值操作符重载

用于将一个对象的值赋给另一个已存在的对象。

区别
  • 拷贝构造函数:在创建新对象时调用。
  • 赋值操作符:在对象已经存在时调用。
代码示例
class Test {
private:int* data;public:// 构造函数Test(int value) {data = new int(value);cout << "Constructor called for value: " << *data << endl;}// 拷贝构造函数Test(const Test& obj) {data = new int(*obj.data);cout << "Copy Constructor called" << endl;}// 赋值操作符重载Test& operator=(const Test& obj) {if (this == &obj) return *this; // 防止自赋值delete data;                    // 释放旧资源data = new int(*obj.data);      // 深拷贝cout << "Assignment Operator called" << endl;return *this;}// 析构函数~Test() {delete data;cout << "Destructor called" << endl;}
};
int main() {Test t1(10);          // 调用构造函数Test t2(20);          // 调用构造函数t2 = t1;              // 调用赋值操作符return 0;
}
输出
Constructor called for value: 10
Constructor called for value: 20
Assignment Operator called
Destructor called
Destructor called

4. 静态对象

静态对象在程序生命周期内只初始化一次,其析构函数会在程序结束时调用。

代码示例
class Test {
public:Test() { cout << "Constructor called" << endl; }~Test() { cout << "Destructor called" << endl; }
};
int main() {static Test t;    // 静态对象cout << "Main function ends" << endl;return 0;
}
输出
Constructor called
Main function ends
Destructor called

5. 动态分配与内存管理

动态分配允许在运行时分配内存,但需手动释放。

代码示例
class Test {
public:Test() { cout << "Constructor called" << endl; }~Test() { cout << "Destructor called" << endl; }
};
int main() {Test* obj = new Test();  // 动态分配单个对象delete obj;              // 释放单个对象Test* arr = new Test[2]; // 动态分配对象数组delete[] arr;            // 释放对象数组return 0;
}
输出
Constructor called
Constructor called
Constructor called
Destructor called
Destructor called
Destructor called

6. 临时对象与优化
  • 临时对象
    • 在表达式中创建的对象,生命周期短。
    • 常用于函数返回值或强制类型转换。
代码示例
class Test {
public:Test(int value) { cout << "Constructor called for value: " << value << endl; }~Test() { cout << "Destructor called" << endl; }
};
int main() {Test t1 = Test(10); // 临时对象return 0;
}
输出
Constructor called for value: 10
Destructor called
  • 优化临时对象
    1. 使用引用传递避免拷贝:
      void func(const Test& obj);
      
    2. 使用移动语义优化临时对象(C++11):
      Test(Test&& obj) noexcept { /* 转移资源 */ }
      

函数调用中的对象行为
  • 示例
    Test getObject(Test t) {Test tmp(t.data);return tmp;
    }
    Test t2 = getObject(t1);
    
  • 背后调用顺序
    1. t1 构造。
    2. 实参传递调用拷贝构造。
    3. 局部对象tmp调用构造函数。
    4. 返回临时对象调用拷贝构造。
    5. 临时对象赋值给t2调用赋值运算符。
    6. 局部对象和临时对象析构。

注意事项
  1. 禁止返回局部对象的指针或引用
    • 局部对象在函数结束时被销毁,返回其地址会导致悬空指针。
  2. 优化建议
    • 使用引用传递避免拷贝。
    • 避免不必要的临时对象生成。

7. 完整示例

以下是一个综合示例,展示对象的构造、拷贝、赋值、动态分配与析构:

#include <iostream>
using namespace std;class Test {
private:int* data;public:// 构造函数Test(int value = 0) {data = new int(value);cout << "Constructor called for value: " << *data << endl;}// 拷贝构造函数Test(const Test& obj) {data = new int(*obj.data);cout << "Copy Constructor called" << endl;}// 赋值操作符Test& operator=(const Test& obj) {if (this == &obj) return *this; // 防止自赋值delete data;data = new int(*obj.data);cout << "Assignment Operator called" << endl;return *this;}// 析构函数~Test() {delete data;cout << "Destructor called" << endl;}
};int main() {Test t1(10);           // 构造函数Test t2 = t1;          // 拷贝构造函数Test t3;               // 默认构造函数t3 = t1;               // 赋值操作符Test* p = new Test(20); // 动态分配delete p;              // 释放动态分配的内存return 0;
}
输出
Constructor called for value: 10
Copy Constructor called
Constructor called for value: 0
Assignment Operator called
Constructor called for value: 20
Destructor called
Destructor called
Destructor called
Destructor called

8. 总结
  1. 构造函数:用于对象初始化,可以有参数或默认值。
  2. 拷贝构造函数:用于复制对象,推荐实现深拷贝。
  3. 赋值操作符:对象赋值时调用,需处理自赋值和旧资源释放。
  4. 析构函数:对象生命周期结束时自动释放资源,避免内存泄漏。
  5. 动态分配:需要deletedelete[]手动释放内存。
  6. 临时对象:生命周期短,尽量优化避免不必要的生成。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词