Singleton类无法找到ctor,但编译,运行并保留实例未初始化
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Singleton类无法找到ctor,但编译,运行并保留实例未初始化相关的知识,希望对你有一定的参考价值。
我在MSVC ++ 17版本15.5.5中实现单例模式时遇到问题。我正在用旗帜/std:c++17
编译。
我的实现包含以下帮助器类:
#pragma once
#include <cassert>
template<class T>
class Singleton : private T
{
public:
virtual ~Singleton() = default;
template<typename ... Targs>
static T & initInstance(Targs && ... args)
{
assert(instance == nullptr);
instance = new Singleton<T>(std::forward<Targs>(args)...); //The constructor of T might be inaccessible here so let our own ctor call it
return *instance;
}
static T & getInstance()
{
assert(instance != nullptr);
return *instance;
}
private:
template<typename ... Targs>
explicit Singleton(Targs && ... args)
: T{ std::forward<Targs>(args)... }
{}
static T * instance;
};
template<class T>
T * Singleton<T>::instance = nullptr;
这种实现的一个目的是使用某种形式的延迟初始化,但没有每次调用if
时执行的冗余getInstance()
语句。只有第一次才有用,因为实例需要初始化,但之后if
只是开销。为此,我创建了函数initInstance()
,在调用getInstance()
之前必须调用它。我很清楚assert()
只能在调试模式下工作,但这对我的项目来说很好。
该类旨在以下列方式使用:
#include "Singleton.h"
#include <iostream>
class Foo
{
public:
virtual ~Foo() = default;
protected: //has no public ctor's
Foo(int i) //has no default ctor
: i{ i }
{
std::cout << "foo ctr " << i << "
"; //Not printed if no ctor of Foo is found
}
private:
int i;
};
int main(int argc, char** argv)
{
Singleton<Foo>::initInstance(5); //Selects and executes Foo(int i).
//Singleton<Foo>::initInstance(); //Should not compile, yet it does. Calls no ctor of Foo at all.
Foo & theOnlyFoo = Singleton<Foo>::getInstance(); //or just use the return value of initInstance(5) to initialize this reference
//...
return 0;
}
问题:
如果我在没有任何参数的情况下调用Singleton<Foo>::initInstance();
,即使Foo
没有默认构造函数,代码仍会编译并运行。我原本预计实例化Singleton<Foo>
的构造函数会失败,因为它调用Foo
的构造函数给出了参数,但在查找时它不应该找到合适的构造函数。然而代码以某种方式编译。
当我执行代码时,Singleton<Foo>
的构造函数被调用,但Foo
本身的构造函数不是。当我在instance
初始化之后在断点处停止执行并检查其数据库i
的值时,它是一个随机的巨大负值,表明没有执行任何代码来初始化Foo
的实例。
只有在没有适当的Foo
构造函数才能调用时才会发生这种情况。当有,一切正常,并调用Foo
的选定构造函数。
正如评论中所建议的,这可能是编译器错误。我提交了一份错误报告。
我还提交了我在评论中描述的内部编译器错误的错误报告。当我(错误地)将using T::T;
放入Singleton<T>::InitInstance()
然后调用T
s构造函数时,会发生内部编译器错误。
以上是关于Singleton类无法找到ctor,但编译,运行并保留实例未初始化的主要内容,如果未能解决你的问题,请参考以下文章
Singleton 类 DataLoader - 在 AppDelegate 中从 Core Data 设置值,但无法访问其他类中的 DataLoader 变量
std::any 用于仅移动模板,其中 copy-ctor 内的 static_assert 等于编译错误,但为啥呢?
依赖项没有复制 ctor 或赋值运算符时的 C++ 初始化程序列表