Когда создается класс с наследованием, сначала вызывается конструктор базового класса, после чего дочерние классы поднимаются вверх в иерархии.Это означает, что в конструкторе Father
, Child/Child2
еще не создан.
Попытка использовать объект до того, как он будет создан, вероятно, приведет к неопределенному поведению.C ++ пытается защитить вас от этого.Прочитайте например FAQ Lite .Это не совсем то же самое, но это связано, и чтение этого должно дать вам представление, почему typeid
сказал бы, что объект является Father
.
В cppreference , который мы можем прочитать
Если typeid используется на строящемся или разрушаемом объекте (в деструкторе или в конструкторе, включая список инициализатора конструктора или инициализаторы членов по умолчанию), то объект std :: type_info, на который ссылается этотtypeid представляет класс, который создается или уничтожается, даже если он не является самым производным классом.
Я видел несколько способов реализации синглетонов, самый современный из них, кажется, возвращает ссылку наобъект статической функции.Вот одна из идей.
#include <iostream>
template <typename T>
T& Singleton() {
static T single;
return single;
}
class Foo {
private:
Foo() {
std::cout << "Constructed" << std::endl;
}
friend Foo& Singleton<Foo>();
public:
void print() {
std::cout << "Foo" << std::endl;
}
};
int main() {
//Foo f; not allowed
Singleton<Foo>().print();
Singleton<Foo>().print();
}
Для этого требуется, чтобы каждый экземпляр-одиночка имел закрытый конструктор и friend
экземпляр шаблона.Только функция Singleton
позволит создать Foo
, и она будет создавать только 1 копию.Это также потокобезопасно, и вам не нужно беспокоиться об очистке.Другие подходы можно найти, если вы гуглите вокруг.