考虑以下代码:
#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;
要求:
我想要的是:尽可能少删除调用(和内存泄漏)。
我的观察:
NULL
并始终delete
delete
FOO::CreateRef
为CreatePtr
时,我可以让NULL
返回一个特殊实例。这将有助于NULL检查,但仍然没有删除。CreatePtr(5)
永远不会被删除,只会复制到local
)
有什么方法可以声明FOO类型的局部变量并在声明中初始化它,以便在函数退出时自动删除它?
答案 0 :(得分:2)
如果无法创建对象,则抛出异常。无论如何它都更有用,因为它提供了更多的上下文,为什么无法创建对象并允许程序解决问题。此外,您还可以避免delete
出现问题,因为您没有使用new
。如果要以多态方式使用该类型,则需要使用std::unique_ptr
或std::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;
}
答案 1 :(得分:0)
不确定是否应该根据情况使用指针。
此外,您不会删除为local
变量创建的指针。
由于FOO
应该是POD并且取决于其大小(取决于SOME_OTHER_BASE
的大小),您可以通过create method中的值返回它:
struct FOO : SOME_OTHER_BASE {
int value;
static FOO Create(int param) {
FOO foo;
foo.value = param;
return foo;
}
};
int main() {
FOO local = FOO::Create(2);
FOO &ref = local;
FOO *ptr = new FOO(FOO::Create(6));
// can check if ptr is NULL if you want
cout << "local: " << local.value << endl;
cout << "ref: " << ref.value << endl;
cout << "ptr: " << ptr->value << endl;
delete ptr;
return 0;
}