c++ - 指针 vs 引用并清理它

标签 c++ delete-operator

考虑这段代码:

#include <iostream>
using namespace std;

struct SOME_OTHER_BASE {
    // members
};

struct FOO : SOME_OTHER_BASE {
    int value;
    static FOO *CreatePtr(int param) 
    { 
        FOO *res = new FOO(); 
        res->value = param; 
        return res;
    }
    static FOO &CreateRef(int param)
    {
        return *CreatePtr(param);
    }
};

int main() {
    FOO *ptr = FOO::CreatePtr(2);
    FOO &ref = FOO::CreateRef(4);
    FOO local = FOO::CreateRef(5);

    cout << "ptr: " << ptr->value << endl;
    cout << "ref: " << ref.value << endl;
    cout << "local: " << local.value << endl;

    delete ptr;
    delete &ref;
    return 0;

要求:

  1. FOO::CreatePtr 方法在某些情况下可能会返回 NULL(分配失败并已被处理、参数无效等)
  2. FOO 是 POD,但不是聚合

我想要的是:尽可能少的删除调用(和内存泄漏)。

我的观察:

  1. 我可以使用 FOO::CreatePtr,检查 NULL,然后总是delete
  2. 我可以使用 FOO::CreateRef,但我无法真正检查是否为 null,我仍然需要delete
    1. CreatePtrNULL 时,我可以让 FOO::CreateRef 返回一个特殊实例。这将有助于 NULL 检查,但仍无助于删除。
  3. 我可以使用本地变体,但我认为我那里存在内存泄漏(CreatePtr(5) 永远不会被删除,只会被复制到 local 中)
    1. 这是非常低效的,因为有一个不必要的分配和一个拷贝
    2. 我不能使用大括号初始化,因为 FOO 不是聚合

有什么方法可以声明 FOO 类型的局部变量并在声明中对其进行初始化,以便在函数退出时自动将其删除?

最佳答案

如果无法创建您的对象,则抛出异常。无论如何,它更有用,因为它提供了更多无法创建对象的上下文,并允许程序修复问题。您还避免了 delete 的问题,因为您不使用 new。如果要以多态方式使用该类型,则需要使用智能指针,例如 std::unique_ptrstd::shared_ptr

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

struct SOME_OTHER_BASE {
    // members
};

struct CreationFailure : std::runtime_error
{
    CreationFailure(const std::string& s) :
        std::runtime_error(s)
    {

    }
};

struct FOO : SOME_OTHER_BASE {
    int value;

    FOO(int value) : 
        SOME_OTHER_BASE(), // pass the constructor arguments
        value(value)
    {
        // additional actions
        if(/* creation failed */)
            throw CreationFailure("out of memory");
    }
};

int main() {
    FOO local(2);

    cout << local.value << endl;
    return 0;
}

如果不能添加构造函数,同样的逻辑可以移到工厂函数中:

FOO createFoo(int v)
{
    FOO f;
    f.value = v;
    if(/* creation failed */)
        throw CreationFailure("out of memory");
    return f;
}

关于c++ - 指针 vs 引用并清理它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29378953/

相关文章:

c++ - 矩阵 vector 乘法优化 - 缓存大小

c++ - Boost 版本在 Ubuntu Trusty 上至少为 1.56

c++ - 获取 LPDIRECT3DVERTEXBUFFER9 上的顶点内容

c++ - 矩阵运算符重载不起作用

c++ - 为什么 GCC 不优化 C++ 中空指针的删除?

c++ - 删除导致有效结构指针中断

C++将字符串输入的二进制转换为十进制

c++ - 仅当它是指针时才删除泛型类型的值

javascript - 如果我已经创建了一个可以访问 window.x 的变量,为什么我不能使用 delete 运算符?

c++ - 使用调试版本在 C API 上调用 delete 到 C++ 接口(interface)段错误