Передача "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 идет по пути?
Ответы
Ответ 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...