[英]Pointers vs references and cleaning it all up
考慮以下代碼:
#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
CreatePtr
為NULL
時,我可以使FOO::CreateRef
返回一個特殊實例。 這將有助於進行NULL檢查,但仍然無法刪除。 CreatePtr(5)
永遠不會被刪除,只會復制到local
)
有什么辦法可以聲明FOO類型的局部變量並在聲明中對其進行初始化,以便在函數退出時將其自動刪除?
如果無法創建對象,則引發異常。 無論如何,它更有用,因為它提供了更多無法創建對象的上下文,並允許程序解決此問題。 另外,由於不使用new
因此可以避免delete
的問題。 如果要多態使用該類型,則需要使用諸如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;
}
不知道是否應該針對您的情況使用指針。
此外,您不會刪除創建到local
變量的指針。
由於FOO
應該是一個POD,並取決於其大小(取決於SOME_OTHER_BASE
的大小),因此可以從create方法中按值返回它:
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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.