[英]Is there a way to assign a stacked object to the allocated memory using placement new?
這是我的程序:
#include <iostream>
using namespace std;
class Object {
public:
Object() { cout << "Object constructor!" << endl; }
~Object() { cout << "Object destructor!" << endl; }
Object(const Object& obj) { information = obj.information; cout << "Copy constructor!" << endl; }
void setInformation(const string info) { information = info; }
string getInformation() const { return information; }
private:
string information;
};
class Storage {
public:
Storage() { object = static_cast<Object*>(operator new(sizeof(Object))); }
~Storage() { operator delete(object); }
void setObject(const Object& obj) {
// Todo: assign obj to the allocated space of the pointer object
}
private:
Object* object;
};
int main()
{
Object o;
o.setInformation("Engine");
Storage storage;
storage.setObject(o);
return 0;
}
在存儲中,我正在分配空間來存儲類型為Object的一個對象而不創建它。 我正在使用new分配內存,並在析構函數中釋放它。 我知道我可以用
object = new(object) Object()
構造一個對象。 但是我可以將已經創建的對象放入內存中嗎? 在我的情況下,調用方法setObject()。 如果是,使用這種內存管理會遇到什么問題? 提前致謝。
實現您要實現的行為的最簡單方法是使用C ++ 17中的std::optional
。 它可以讓你的“儲備”為您的存儲Object
沒有構建它,並且不使用堆 。 它還將處理所有構造函數和析構函數調用。
這也可以在沒有std::optional
情況下完成,但是您實際上必須自己實現類似的解決方案。 無論如何,您都需要一個額外的成員來指定是否構造對象,以便您可以正確地處理銷毀和分配。
然后,您的setObject
方法將如下所示:
void setObject(const Object& obj) {
if (constructed) {
*object = obj;
} else {
new (object) Object(obj);
constructed = true;
}
}
要利用移動語義,您可以像這樣修改您的方法:
void setObject(Object obj) {
if (constructed) {
*object = std::move(obj);
} else {
new (object) Object(std::move(obj));
constructed = true;
}
}
請注意,現在setObject
接受它的參數按值,因此它可以與lvalue和rvalue引用一起使用以構造參數,然后將其移動到成員中。
new放置是一個相當高級的構造,而擁有一個Object*
實際上指向未初始化的內存的想法相當令人恐懼。 我可以建議您讓您的生活更輕松嗎?
class Storage {
void setObject(const Object& obj) {
if (object) {
*object = obj;
} else {
object.reset(new Object(obj));
}
}
private:
std::unique_ptr<Object> object;
};
這需要在Object
類上使用復制構造函數和賦值運算符,但是使用C ++時要習慣得多。 並且在所示的Object
實現中,默認的,由編譯器提供的實現已經可以了。
只是澄清一下:
但是我可以將已經創建的對象放入內存中嗎?
你不能。 沒有辦法在C ++中移動對象到內存中。 對於平凡可復制的類型,你可以復制(例如,通過memcpy
或memmove
)他們的記憶表示。 但這實際上並沒有任何作用。 此外,您的Object
類不可復制。
您可以移動的是對象的內容,這就是移動語義的目的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.