Можно ли разыменовать объект другим объектом внутри его собственного метода? - PullRequest
2 голосов
/ 19 февраля 2020

У меня есть вопрос о какой-то проблеме C ++. Допустим, у меня действительно большой класс с именем BigClass и я говорю BigClass* foo = new BigClass();

Допустим, у меня есть метод внутри BigClass, который определяет другой локальный объект tmp типа BigClass и в конце метода Я проверяю, была ли ошибка, выполняя некоторые действия с tmp, а если нет, то хочу разыменовать this к этому объекту. Я не хочу копировать все аргументы из tmp в this, потому что объект слишком большой и процесс будет медленным. Есть ли способ разыменования объекта внутри его собственного метода?

Пример:

class BigClass
{
    int a;
    long b;
    std::vector<int> c;
    // other members...

    void replace()
    {
        BigClass* tmp = new BigClass();
        // do some calculations with tmp
        *this = tmp; // problem
    }
}

Почему * this = tmp является проблемой?

Я определил оператор =, который просто делает что-то вроде этого:

this.a = src.a;
this.b = src.b;
this.c = src.c;
.
.
.

Но там я делаю копию всех переменных-членов, и это медленно. Я хочу просто разыменовать объект вместо копирования всех переменных-членов.

1 Ответ

2 голосов
/ 19 февраля 2020

Если вы не хотите копировать, вы можете вместо этого переместить его:

struct BigClass {
    void func() {
        BigClass tmp;

        *this = std::move(tmp);
    }
};

Операция перемещения обычно не включает динамическое c выделение или копирование больших буферов.

Если вы следуете правилу нуля , для вас будет определен оператор назначения перемещения.

В противном случае вы всегда можете определить его с помощью оператора по умолчанию:

struct BigClass {
    BigClass& operator=(BigClass&&) = default;

    // ...
};

Вы также можете написать свой собственный оператор, но по умолчанию обычно выполняет свою работу очень хорошо.

struct BigClass {
    //          quite important ----v------v
    BigClass& operator=(BigClass&& rhs) noexcept {
        this->a = std::move(rhs.a);
        this->b = std::move(rhs.b);
        this->c = std::move(rhs.c);
    }

    // ...
};

Операция перемещения обычно очень быстрая и намного быстрее, чем new.


Кроме того, вы также можете обновить объект и назначить ему указатель:

struct BigClass {
    auto replace() -> BigClass* {
        auto tmp = new BigClass{};

        // ...

        return tmp;
    }
};

Остерегайтесь, так как он намного медленнее, поскольку включает динамическое распределение c.

...