Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;单例继承问题_C++_Oop_Inheritance_Singleton - Fatal编程技术网

C++ C++;单例继承问题

C++ C++;单例继承问题,c++,oop,inheritance,singleton,C++,Oop,Inheritance,Singleton,我试图为我的子类实现一个简单的继承单例模式。 因此,我正在实现一个父类,因为我想让其他人尽可能容易地创建一个新的单例子类,所以我需要在父类构造函数中处理子类单例实现所需的所有操作 #include <vector> #include <typeinfo> #include <iostream> class Father { protected: Father() { for(auto & instance : Fath

我试图为我的子类实现一个简单的继承单例模式。 因此,我正在实现一个父类,因为我想让其他人尽可能容易地创建一个新的单例子类,所以我需要在父类构造函数中处理子类单例实现所需的所有操作

#include <vector>
#include <typeinfo>
#include <iostream>

class Father
{
protected:
    Father()
    {
        for(auto & instance : Father::singletonInstances)
            if(typeid(instance) == typeid(this))    //    typeid(this) will always be "Father", which is actually the issue
            {
                //  Singleton instance already exists for this class
                * this = instance;
                std::cout<<"An instance of the given class is already active\n";

                return;
            }

        std::cout<<"Constructed\n";

        //  Otherwise, mark this as the Singleton instance for this class
        Father::singletonInstances.emplace_back(this);
    }
public:
    Father operator=(Father * inputObj) { return * inputObj; }
private:
    static std::vector<Father *> singletonInstances;
};

std::vector<Father *> Father::singletonInstances;

class Child : protected Father
{
public:
    Child() : Father() {}
};

class Child2 : protected Father
{
public:
    Child2() : Father() {}
};

int main()
{
    new Child();
    new Child2();

    return 0;
}
因此,要再次说明问题: -问题是typeid(this)在构造函数中始终是“父” -新生儿();新生儿2();应该允许 -新生儿();新生儿();不应该被允许 -不应对子类进行任何修改

我知道我的Singleton实现可能看起来很奇怪。我乐于接受新思想


我在JScript实现了这些思想,但是在C++中,我找不到一种方法来实现它。

< P>当创建继承类时,首先调用基类构造函数,然后在层次结构中对子类进行向上调用。这意味着在父的构造函数中,
Child/Child2
尚未构造

在构建对象之前尝试使用该对象可能会导致未定义的行为。C++试图保护你不受此影响。例如阅读。这不是完全相同的事情,但是相关的和阅读这篇文章应该会让你知道为什么
typeid
会说对象是
父对象

我们可以看书

如果typeid用于正在构造或销毁的对象(在析构函数或构造函数中,包括构造函数的初始值设定项列表或默认成员初始值设定项),则此typeid引用的std::type_info对象表示正在构造或销毁的类,即使它不是最派生的类

我见过几种实现单例的方法,最现代的方法似乎是返回对静态函数对象的引用。这里有一个想法

#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();
}
#包括
模板
T&Singleton(){
静态T单;
返回单;
}
福班{
私人:
Foo(){

std::cout创建具有继承的类时,首先调用基类构造函数,然后调用层次结构中向上的子类。这意味着在父类的构造函数中,
子类/Child2
尚未构造

在构造之前尝试使用对象可能会导致未定义的行为。C++试图保护您不受此影响。例如,读取。这不是完全相同的事情,但相关和阅读这应该给您一个想法:为什么代码> Type ID < /C>会说对象是<代码>父< /代码>。 我们可以看书

如果typeid用于正在构造或销毁的对象(在析构函数或构造函数中,包括构造函数的初始值设定项列表或默认成员初始值设定项),则此typeid引用的std::type_info对象表示正在构造或销毁的类,即使它不是最派生的类

我见过几种实现单例的方法,最现代的方法似乎是返回对静态函数对象的引用

#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();
}
#包括
模板
T&Singleton(){
静态T单;
返回单;
}
福班{
私人:
Foo(){

std::非常感谢您的回答!我知道这是正常的构造顺序。无论哪种方式,您能否提供一个替代方案,在不修改子类的情况下找出哪个子类称为父构造函数?如果不,您能否提供另一个有效的替代方案?@SergiuNistor我用一种方法更新了答案关于它。这不一定是最好的,但我觉得它是一个相当干净的方式。再次感谢你的回答!尽管它不是我想象的那样,但它确实是一个很酷的实现。感谢你的努力!感谢你的回答!我知道这是正常的构造顺序。无论哪种方式,你能为我提供一个替代方法来发现它吗哪个子类称为父构造函数,而不修改子类?如果不是,你能给我提供另一个有效的替代方案吗?@SergiUnitor我用一种方法更新了答案。这不一定是最好的,但我发现它是一种相当干净的方法。再次感谢你的答案!尽管它不是我想象的那样,但它是正确的这是一个非常酷的实现。感谢您的努力!