Подтвердить что ты не робот

Передача "this" функции из конструктора?

Могу ли я передать "this" функции в качестве указателя из конструктора класса и использовать ее для указания на членов объекта до того, как конструктор вернется?

Безопасно ли это делать, если доступ к элементам правильно инициализирован до вызова функции?

В качестве примера:

#include <iostream>

class Stuff
{
public:
    static void print_number(void *param)
    {
        std::cout << reinterpret_cast<Stuff*>(param)->number;
    }

    int number;

    Stuff(int number_)
        : number(number_)
    {
        print_number(this);
    }
};

void main() {
    Stuff stuff(12345);
}

Я думал, что это не сработает, но похоже. Является ли это стандартное поведение, или просто поведение undefined идет по пути?

4b9b3361

Ответ 1

Когда вы создаете экземпляр объекта в С++, код в конструкторе является последней выполненной. Вся другая инициализация, включая инициализацию суперкласса, выполнение конструктора суперкласса и распределение памяти, происходит заранее. Код в конструкторе действительно просто для выполнения дополнительной инициализации после создания объекта. Поэтому вполне целесообразно использовать указатель "this" в конструкторе класса и предположить, что он указывает на полностью построенный объект.

Конечно, вам все равно нужно остерегаться неинициализированных переменных-членов, если вы еще не инициализировали их в своем коде конструктора.

Ответ 2

Вы можете найти хороший ответ на этот здесь.

Все унаследованные члены и члены вызывающего класса гарантированно создаются в начале выполнения кода конструктора и поэтому могут быть безопасно указаны в нем.

Основной вопрос заключается в том, что вы не должны вызывать виртуальные функции на this. В большинстве случаев я пробовал это, он просто заканчивает вызов функции базового класса, но я считаю, что стандарт говорит, что результат undefined.

Ответ 3

В качестве примечания к представленному коду я бы вместо этого заплатил шаблон void*:

class Stuff
{
public:
    template <typename T>
    static void print_number(const T& t)
    {
        std::cout << t.number;
    }

    int number;

    Stuff(int number_)
    : number(number_)
    {
        print_number(*this);
    }
};

Затем вы получите ошибку компиляции, если тип t не имеет члена number.

Ответ 4

Энди, я думаю, вы ошибаетесь в части undefined стандарта.

Когда вы находитесь в конструкторе, "this" является указателем на объект, тип которого является базовым классом объекта, который вы создаете, а это означает, что виртуальные функции, частично реализованные в будет вызываться базовый класс, а указатели в виртуальной таблице не будут выполняться.

Дополнительная информация в С++ Faq Lite...