簡體   English   中英

有沒有一種方法可以使用placement new將堆棧的對象分配給分配的內存?

[英]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 ++中移動對象到內存中。 對於平凡可復制的類型,你可以復制(例如,通過memcpymemmove )他們的記憶表示。 但這實際上並沒有任何作用。 此外,您的Object類不可復制。

您可以移動的是對象的內容,這就是移動語義的目的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM