gpt4 book ai didi

c++ - 返回一个对象会调用它的析构函数吗?

转载 作者:搜寻专家 更新时间:2023-10-31 00:38:20 30 4
gpt4 key购买 nike

我有一个非常简单的类来处理回调。来电者要求经理回叫。只要调用者持有回调对象,它就一直有效。但是,一旦对象死亡,它的析构函数就会将管理器内部的指针设置为 NULL,这样它就知道在下次遇到它时将其丢弃。

...或者至少,这是我追求的基本理念。

class Manager{
public:
void executeOnList() { ... }

Callback requestCallback(Drawable * target){
Drawable ** ptr = list.add(target);
return Callback(ptr); // <-- the point of interest
}
private:
List list;
};


class Callback{
friend Manager;
private:
Callback(Drawable ** targetPtr){
drawablePtr = targetPtr;
}
public:
~Callback(){
(*drawablePtr) = NULL; // <-- dtor of interest
}
private:
Drawable ** drawablePtr;
};

我的问题是,Manager::requestCallback() 会在将结构返回给它的调用者之前调用 Callback 的析构函数吗?

如果是这种情况,是否有任何方法可以防止这种情况发生,同时(或多或少)保持 Callback 功能背后的基本思想?

最佳答案

堆栈中的每个对象在超出范围时都会自动销毁。也就是说,从概念上讲,临时对象在从函数返回时将超出范围。也就是说,当返回复制的对象时,编译器可能会忽略它,在这种情况下,返回语句中的临时对象似乎根本不存在。但是,复制省略是否发生是一种优化,并不能保证。

在你的情况下,仅仅依赖于析构函数似乎不起作用。然而,可能有用的是区分传递的临时对象和持有(命名或指向)的对象。基本思想是将指向指针视为对象拥有的资源,并仅在实际所有者被销毁(类似于 std::unique_ptr<T> )或所有所有者被销毁(类似于 std::shared_ptr<T> )时重置它。假设你可以使用右值引用,你可以把两种形式都弄对,否则你只能得到共享所有权的权利。

以下是单一所有权逻辑的简要概述:

class Callback{
friend Manager;
private:
Callback(Drawable ** targetPtr){
drawablePtr = targetPtr;
}
public:
Callback(Callback&& other):
drawablePtr(other.drawablePtr) {
other.drawablePtr = 0;
}
~Callback(){
if (drawablePtr) {
(*drawablePtr) = 0;
}
}
private:
Drawable ** drawablePtr;
};

如果您不能使用右值语义,实际上您仍然可以使用相同的逻辑,但是存在创建拷贝时“资源”被意外从命名对象中窃取的风险。使用移动构造函数可以避免这种风险。

关于c++ - 返回一个对象会调用它的析构函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18298336/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com