(Re) Инициализация объекта без конструктора копирования в cpp - PullRequest
0 голосов
/ 12 февраля 2019

Этот вопрос предназначен для встроенных систем!

У меня есть следующие варианты инициализации объекта:

Object* o = new Object(arg);

Это помещает объект в кучу и возвращает указатель на него.Я предпочитаю не использовать динамическое распределение во встроенном программном обеспечении.

Object o = Object(arg);

Это создает новый объект в стеке, а затем копирует его в объект o и удаляет его после.Это может вызвать переполнение стека, если объект достаточно большой, чтобы поместиться в ОЗУ, но не в стеке.Я видел, как это происходит при отключенной оптимизации, я не исследовал, отличается ли она от включенной оптимизации.

Object o(arg);

Это создает объект без копирования, однако как я могу "инициализировать" oеще раз?

Для встроенных систем я предпочитаю последний вариант, поскольку куча не используется, и в стеке нет временного объекта, который мог бы переполнить стек.

Однако я озадачен тем, как я могу это сделатьповторная инициализация объекта снова, так как:

o.Object(arg)

не разрешено.

Я мог бы создать метод с именем init (arg) и вызвать

o.init(arg)

, который делает то же самоеинициализация Object::Object(arg), но я бы предпочел не создавать дополнительный метод с "нестандартным" именем, которое мне нужно запомнить.

Есть ли способ вызвать конструктор уже созданного объекта длязаново инициализировать его, не делая копию?

Ответы [ 3 ]

0 голосов
/ 12 февраля 2019

Рассмотрите возможность размещения нового в текущей памяти вашего объекта.Это инициализирует новый объект в используемой в данный момент памяти без выделения новой памяти.Это может быть решением для вас.Например:

new (&o) Object(args)

Попробуйте:

#include <iostream>

class A
{
public:

    A(int i)
    {
        m_i = i;
    }

    int m_i;
};

int main()
{
    int s = 10;
    int *ps = new (&s) int(100);
    std::cout << *ps;
    std::cout << s;

    A a(5);
    new (&a) A(49);
    std::cout << a.m_i;
}

g++ -std=c++98 main.cpp возвращает 10010049, что является правильным.

0 голосов
/ 12 февраля 2019

Шаг 1. Получите компилятор, который работает (который распознает наиболее очевидные возможности инициализации объекта на месте) и поддерживает по крайней мере C ++ 11.

Шаг 2. Для инициализации используйте:

auto o = Object(arg); // won't copy ever with optimization turned on

Если вам нужно переназначить новые аргументы конструктору:

o = Object(arg1); // calls move asignment operator

Если вам нужно перезаписать значениесо значением другого объекта (который вы не планируете использовать впоследствии:

o = std::move(o1); // o1 is the other Object, afterwards o1 is left in 'valid but undefinded state'

Если это не сработает для вас (все еще стучат в стеке / нет оператора назначения перемещения и т. д.), вам, вероятно, следуетперейти на размещение нового, явно вызывая деструктор, как предлагает @tomer zeitune:

o.~Object(); // cleanup
new (&o) Object();

Явный вызов деструктора необходим, например, для освобождения всех ресурсов, управляемых объектом.

0 голосов
/ 12 февраля 2019

Вам нужно использовать размещение new и вызвать пример деструктора объекта ниже

A a = A();//init
a.~A();//clear
new (&a) A();//re init
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...