C++单例继承问题

标签 c++ oop inheritance singleton

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

#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;
}

输出:

Constructed
An instance of the given class is already active

所以,再次澄清一下: - 问题是 typeid(this) 在构造函数中总是“父亲” - 新的 child ();新的 Child2();应该允许 - 新的 child ();新的 child ();不应该被允许 - 不应对子类进行任何修改

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

我能够在 JScript 中实现这些想法,但在 C++ 中我似乎无法找到使其工作的方法。

最佳答案

当创建具有继承的类时,首先调用基类构造函数,然后在层次结构中向上调用子类。这意味着在Father的构造函数中,Child/Child2还没有构造。

在构造对象之前尝试使用该对象可能会导致未定义的行为。 C++ 试图保护你免受这种情况的影响。阅读例如 the FAQ Lite .这不是完全相同的东西,但是相关联并阅读本文应该让您了解为什么 typeid 会说该对象是 Father

关于 cppreference我们可以阅读

If typeid is used on an object under construction or destruction (in a destructor or in a constructor, including constructor's initializer list or default member initializers), then the std::type_info object referred to by this typeid represents the class that is being constructed or destroyed even if it is not the most-derived class.

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

#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();
}

这要求每个单例实例都有一个私有(private)构造函数并友好模板实例化。只允许 Singleton 函数构造一个 Foo 并且它只会构造 1 个拷贝。它也是线程安全的,您无需担心清理问题。如果您四处搜索,可以找到其他方法。

关于C++单例继承问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50786149/

相关文章:

java - 尝试覆盖方法时奇怪的 Eclipse 行为

c# - 为测验评分的正确方法

c# - 接口(interface)可以在 C# 中有静态变量吗

c++ - 计算刚体惯性张量世界坐标

c++ - =默认忽略访问说明符?

c# - 在 C# 中删除 "static"引用

java - 继承困惑 - 在构造函数中打印时值为 "this"

postgresql - 使用 CREATE TABLE INHERITS 时如何继承注释

c++ - 在同一对象的成员之间传递 ifstream 变量,C++

c++ - 如何将 lapack 与 CMake 和 Visual 2013 链接起来?