C ++: как вызвать конструктор-член за пределами списка инициализаторов при построении объекта?

Ответ пользователя Pumbaa80 велик, если у вас есть объект, который вы хотите напечатать. Если вы начинаете с правильной строки JSON, которую вы хотите напечатать, вам нужно сначала преобразовать ее в объект:

var jsonString = '{"some":"json"}';
var jsonPretty = JSON.stringify(JSON.parse(jsonString),null,2);  

Это создает объект JSON из строки, а затем преобразует его Вернемся к строке, используя симпатичную печать JSON stringify.

3
задан gsamaras 13 July 2018 в 07:57
поделиться

4 ответа

Вы можете использовать объединение для этого (требуется C ++ 11):

#include <new>

class Foo {
    public:
        Foo(int a) { }
};

class Bar {
    public:
        Bar() {
            new(&m_foo) Foo(42); // call the constructor
            // you can use m_foo from this point
        }

        ~Bar() {
            m_foo.~Foo(); // call the destructor
        }

    private:
        union { // anonymous union
            Foo m_foo;
        };
};

Обратите внимание, что вам нужно явно вызвать деструктор m_foo в ~Bar().

0
ответ дан geza 17 August 2018 в 13:23
поделиться

Нет.

Вы не можете вызвать конструктор класса-члена вне списка инициализаторов.

PS: Даже если вы не вызываете его самостоятельно в списке инициализаторов, тогда компилятор сделает это неявным образом.


Если вы не можете вызвать его в списке инициализаторов, и вы не хотите использовать метод, подобный init, передумайте свой дизайн / подход.

5
ответ дан gsamaras 17 August 2018 в 13:23
поделиться
  • 1
    & Quot; no & quot; как ответ на «как» вопрос несколько странный;) – Max Langhof 13 July 2018 в 08:00
  • 2
    Английский язык такой плохой язык @MaxLanghof. Но если у вас есть предложение обо мне перефразировать, пожалуйста, дайте мне знать. – gsamaras 13 July 2018 в 08:01
  • 3
    Речь шла о вызове конструктора члена из конструктора базового класса. Почему этот ответ, который говорит о конструкторе базового класса, верен для этого вопроса? – mfromla 13 July 2018 в 08:19
  • 4
    @mfromla, потому что я сделал ошибку, обновил, спасибо! – gsamaras 13 July 2018 в 08:22

У вас есть два варианта: использование динамического хранилища или размещение нового.

Первое очевидно (как указано в комментариях, вы можете использовать unique_ptr). Если вы хотите этого избежать, вы можете попробовать разместить новое с помощью std::aligned_union в качестве хранилища:

class SomeClass { ... };

class Owner
{
public:
    Owner()
    {
        m_ptr = new(&m_storage) SomeClass();
    }

    ~Owner()
    {
         m_ptr->~SomeClass();
    } 

private:
    std::aligned_union<0, SomeClass> m_storage;
    SomeClass* m_ptr;
};

Примечание: в этом случае вы несете ответственность за вызов деструктора объект, как показано выше.

Вы можете обернуть m_ptr с помощью unique_ptr (с удаленным, который вызывает только деструктор), чтобы этого избежать:

struct DtorDeleter 
{ 
    template<typename T>
    void operator ()(T* ptr) { ptr->~T(); } 
};

std::unique_ptr<SomeClass, DtorDeleter> m_ptr; // no need to call destructor manually
3
ответ дан joe_chip 17 August 2018 в 13:23
поделиться
0
ответ дан Jarod42 6 September 2018 в 09:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: