Некоторые люди чувствуют, вы не должны использовать this
указатель в конструкторе, потому что объект еще не сформирован полностью. Однако вы можете использовать это в конструкторе (в {body} и даже в списке инициализации), если будете осторожны.
Это то, что всегда работает: конструктор (или функция, вызванный конструктором) может надежно получить доступ к элементам данных, объявленным в базовом классе и/или элементам данных, объявленным в собственном классе конструктора. Это связано с тем, что все те элементы данных гарантированы, что они были полностью построены к моменту начала работы {body} конструктора.
Это то, что никогда не работает: конструктор (или функция, называемый конструктором) не может перейти к производному классу, вызвав функцию virtualmember, которая переопределена в производном классе.Если ваша цель состояла в том, чтобы перейти к переопределенной функции в производном классе, вы не получите то, что хотите. Обратите внимание, что вы не получите переопределение в производном классе независимо от того, как вы вызываете функцию виртуального участника: явно используя этот указатель (например, this-> method()), неявно используя этот указатель (например, метод ()) или даже вызов какой-либо другой функции, которая вызывает функцию виртуального члена на вашем этом объекте. Суть в том, что даже если вызывающий объект создает объект производного класса, во время конструктора базового класса ваш объект еще не является этим производным классом. Вы были предупреждены.
Это то, что иногда работает: если вы передаете какой-либо элемент данных этого объекта другому инициализатору элемента данных, вы должны убедиться, что другой элемент данных уже инициализирован. Хорошей новостью является то, что вы можете определить, был ли другой элемент данных (или не был) инициализирован с использованием некоторых простых правил языка, которые не зависят от конкретного используемого вами компилятора. Плохая новость заключается в том, что вы должны знать эти языковые правила (например, сначала инициализируются под-объекты базового класса (посмотрите порядок, если у вас есть множественное и/или виртуальное наследование!), Тогда члены данных, определенные в классе, инициализируются в порядок, в котором они появляются в объявлении класса). Если вы не знаете эти правила, не передавайте ни одного члена данных из этого объекта (независимо от того, используете ли вы это явное использование явно) для любого другого инициализатора элемента данных! И если вы знаете правила, будьте осторожны.
@gilbertc: Если B происходит от A, даже если вы запустите поток в конце конструктора A, все из B (vtable, переменные-члены, код конструктора) не будут инициализированы/выполнены. Может ли это быть неприятной ошибкой параллелизма? На первый взгляд, я бы сказал, да, потому что объект будет меняться в потоке строительства, в то время как он может быть использован во вновь созданном потоке. – paercebal