【问题标题】:Pointer to object and destructor指向对象和析构函数的指针
【发布时间】:2021-07-25 20:27:45
【问题描述】:

我试图理解为什么我的代码不使用类名的析构函数。实际上我写了两个类。第一个称为 Name,第二个称为 Person,它们有一个指向对象 Name 的指针。我不明白的是为什么程序不调用 Name 的析构函数,因为我认为当我写“new”时我创建了一个新对象,所以它必须在关闭程序之前调用类 Name 的析构函数。

你能解释一下我的理解有什么问题吗?谢谢!

class Name
{
private:
    string name;
public:
    Name(string name) : name(name) { cout << "Hello " << name << endl; }
    ~Name() { cout << "See you soon " << name; }
};
class Person
{
private:
    Name* myname;
public:
    Person(string name) { myname = new Name(name); }
    ~Person() { cout << "Exit" << endl; }
};

int main()
{
    Person("Marc");
    Person("Alex");
}

【问题讨论】:

  • 当你写 new 时,你明确地说“我稍后会打电话给 delete”。其他人说小猫死了,对此不确定。
  • 当你使用new 时,“它”不需要做任何事情。清理工作由您负责。
  • 因为对象永远不会被销毁?

标签: c++ object pointers destructor


【解决方案1】:

您在这里创建了内存泄漏,因为您在这里创建了Name 的新实例

Person(string name) { myname = new Name(name); }

但你永远不会删除它。这就是为什么 Name 的 destrcutor 永远不会被调用的原因。

为避免这种情况,您可以使用std::unique_ptrstd::shared_ptr,它们将自动处理此类对象的生命周期。

std::unique_ptr<Name> myname;
Person(string name) { myname = std::make_unique<Name>(name); }

另一种方法是删除析构函数中的对象,但在C++ 中,您应该避免直接处理动态原始指针。

#include <iostream>
#include <memory>

class Name
{
private:
    std::string name;

public:
    Name(std::string name) : name(name) { std::cout << "Hello " << name << std::endl; }
    ~Name() { std::cout << "See you soon " << name << std::endl; }
};
class Person
{
private:
    std::unique_ptr<Name> myname;

public:
    Person(std::string name) { myname = std::make_unique<Name>(name); }
    ~Person() { std::cout << "Exit" << std::endl; }
};

int main(int argc, char **argv)
{
    Person("Marc");
    Person("Alex");

    return 0;
}

【讨论】:

  • (你应该避免newdelete的原因是因为它很容易出错。不过普通指针完全没问题。)
  • @user253751,我添加了dynamic raw pointers,以使其更清晰。
  • 实际上,当你没有理由使用指针时,你应该避免使用指针。这个例子根本不需要指针。
  • @user253751,虽然这对于给定的示例可能是正确的,但为了在 SO 上发布,这可能是一个精简的示例。
【解决方案2】:

因为Person类中的myname对象是一个指针。对于每个指针,都必须有一个 delete 语句来释放内存。

将 Person 的类 Destructor 替换为:

~Person() { 
        cout << "Exit" << endl;
        delete myname;
    }

【讨论】:

  • 值得一提的是,这修复了 OP 当前代码中的泄漏,但由于忽略了 rule of 3/5Person 仍然被破坏
猜你喜欢
  • 2012-04-15
  • 1970-01-01
  • 2012-01-22
  • 2021-11-28
  • 2019-06-20
  • 1970-01-01
  • 2012-10-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多