[Lang] 构造与析构

[Lang] 构造和析构

1. 深拷贝与浅拷贝

  • 浅拷贝是在复制对象时,仅复制对象的成员变量的值,而不考虑这些成员变量是否指向了动态分配的内存或其他资源。也就是说,浅拷贝只复制指针的值,不复制指针所指向的内容。编译器默认提供的拷贝构造函数是浅拷贝。
  • 深拷贝是在复制对象时,不仅复制对象的成员变量的值,而且会复制指针所指向的内存或资源。这意味着每个对象拥有自己的独立副本,不会共享内存或资源。

当类涉及动态内存分配时,必须使用深拷贝,避免悬空指针问题。

#include<iostream>
#include<cstring>
using namespace std;

class MyString
{
private:
    char *str;
public:
    // 无参构造
    MyString()
    {
        str = nullptr;
        cout << "无参构造" << endl;
    }

    // 有参构造
    MyString(const char *s)
    {
        str = new char[strlen(s) + 1];
        strcpy(str, s);
        cout << "有参构造" << endl;
    }

    // 拷贝构造
    MyString(const MyString &s)
    {
        str = new char[strlen(s.str) + 1];
        strcpy(str, s.str);
        cout << "拷贝构造" << endl;
    }

    // 析构函数
    ~MyString()
    {
        if (str != nullptr) delete[] str;
        cout << "析构函数" << endl;
    }

    void set(const char *s)
    {
        if (str != nullptr) delete[] str;
        str = new char[strlen(s) + 1];
        strcpy(str, s);
    }

    void print()
    {
        cout << str << endl;
    }
};

int main()
{
    MyString s1;
    MyString s2("hello, world!");
    MyString s3(s2);
    s1.set("Hello, World!");
    s1.print();
    s2.print();
    s3.print();
    return 0;
}
[Running] cd "d:\CppDev\Lang\constructor\" && g++ test1.cpp -o test1 && "d:\CppDev\Lang\constructor\"test1
无参构造
有参构造
拷贝构造
Hello, World!
hello, world!
hello, world!
析构函数
析构函数
析构函数

[Done] exited with code=0 in 1.121 seconds

2. 构造与析构的顺序

  • 构造:当创建一个对象时,首先调用构造函数。对于基类和派生类,基类的构造函数先被调用,然后是派生类的构造函数。
  • 析构:当对象被销毁时,首先调用派生类的析构函数,然后是基类的析构函数。这保证了派生类中使用的资源可以先被正确释放。
#include<iostream>
using namespace std;

class ParentClass
{
public:
    ParentClass()
    {
        cout<<"父类构造函数"<<endl; 
    }
    ~ParentClass()
    {
        cout<<"父类析构函数"<<endl; 
    }
};

class ChildClass : public ParentClass
{
public:
    ChildClass()
    {
        cout<<"子类构造函数"<<endl; 
    }
    ~ChildClass()
    {
        cout<<"子类析构函数"<<endl;
    }    
};

int main()
{
    ChildClass obj;
    return 0;
}
[Running] cd "d:\CppDev\Lang\constructor\" && g++ test2.cpp -o test2 && "d:\CppDev\Lang\constructor\"test2
父类构造函数
子类构造函数
子类析构函数
父类析构函数

[Done] exited with code=0 in 0.917 seconds

3. malloc/free与new/delete区别

  • 构造和析构: malloc/free 只负责内存的分配和释放,而不涉及对象的构造和析构。new/delete 则同时负责内存内存管理和构造析构。
  • 类型安全: new 是类型安全的,它返回正确类型的指针,不需要进行强制类型转换。而 malloc 返回 void* 指针,需要显式转换类型。
  • 错误处理: malloc 在分配失败时返回 NULL,而 new 在分配失败时会抛出 std::bad_alloc 异常。
posted @ 2024-08-13 22:55  yaoguyuan  阅读(6)  评论(0编辑  收藏  举报