【问题标题】:In C++ if I reference an object with a deallocating destructor ~MyClass, will the reference going out of scope invoke the destructor?在 C++ 中,如果我使用释放析构函数 ~MyClass 引用一个对象,超出范围的引用会调用析构函数吗?
【发布时间】:2012-01-21 23:09:59
【问题描述】:

下面的方法总是有效吗?

class MyCLass {
    int *pInt;
public:
    MyCLass() {
        pInt = new int;
        *pInt = 42;
    }
    ~MyCLass() {
        delete pInt;
        printf("Goodbye cruel world!");
    }
    void func1() {
        printf("Hello World %d", *pInt);
    }
};

MyCLass foo;
{
    MyClass &bar = foo;
    //Do stuff
}
foo.func1();

我担心完全模拟原始对象bar 的任务会导致析构函数超出范围时被调用。

【问题讨论】:

  • MyCLass foo = new MyClass(); MyCLass 有一个带有MyClass 指针的构造函数,否则这是行不通的。
  • 语法错误,很好发现,感谢cli_hit,原理保持不变。
  • 构造函数的作用与问题完全无关。你可能会问,引用生命周期的结束是否会导致调用裁判的析构函数。这当然是错误的。
  • C++ 中既没有“授权”也没有“仿真”。引用只是一个别名。

标签: c++ reference scope


【解决方案1】:

不,不会的。在您的示例中,存储与 foo 完全相关。当 foo 超出范围时,将调用析构函数。

当然,如果您仍然有对该对象的引用,则该引用将引用一个现在不存在的对象,这可能会给您带来问题。

引用不模拟原始对象。它所做的只是说,当该对象存在时,通过引用进行的任何调用都将重定向到该对象。

【讨论】:

  • 我感谢(您的快速响应和)您的建议,即它不模拟该对象,从 C 背景来看,它在我看来正是它在做什么,这就是为什么我坚持使用指针这么久。
  • @John:引用和指针几乎是一回事。如果您检查汇编程序,您会发现引用通常以与指针相同的方式实现。
  • 引用不可重新安装,而指针可以。它们是如何实现的并不重要,因为如果没有未定义的行为,您将无法使用像指针这样的引用。
  • 我对答案感到困惑。您说“当 foo 超出范围时,将调用析构函数。”但我认为问题是当 bar 超出范围时会发生什么。
【解决方案2】:

对对象的引用和(原始)指针不管理它的生命周期。因此,当任何一个超出范围时,真实对象都不会被破坏。否则,您无法创建指向堆栈分配对象的引用或指针,因为它们随后会被销毁多次(当引用/指针超出范围以及对象本身超出范围时)。在我看来,理解 c++ 引用的最简单方法是将它们视为无法重新分配的指针,并且每次访问都会自动取消引用(基本上是语法糖,用于向程序员隐藏指针)。

作为旁注,您的代码不是正确的 c++。 MyCLass foo = new MyClass() 声明了一个MyClass 类型的(堆栈分配的)对象,但尝试将new MyClass() 的结果分配给它,它是一个指向MyClass 类型的堆分配对象的指针。初始化foo 的正确方法是MyClass foo;

【讨论】:

    猜你喜欢
    • 2018-09-15
    • 1970-01-01
    • 2012-06-14
    • 2012-09-26
    • 2016-09-26
    • 1970-01-01
    相关资源
    最近更新 更多