[英]C++ Link Error when I was implementing template Singleton class
I'm implementing a Singleton template in C++.我在 C++ 中实现了一个 Singleton 模板。 I try to achieve thread-safe by std::call_once and std::once_flag, but somehow link error happens.
我尝试通过 std::call_once 和 std::once_flag 实现线程安全,但不知何故发生了链接错误。
singleton.h singleton.h
#ifndef _SINGLETON_H_
#define _SINGLETON_H_
#include <boost/noncopyable.hpp>
#include <mutex>
template<typename T>
class Singleton : boost::noncopyable {
public:
Singleton() = delete;
static T& getInstance() {
std::call_once(init_flag_, &Singleton::init);
return *val_;
}
private:
static void init() {
val_ = new T();
}
private:
static std::once_flag init_flag_;
static T* val_;
};
#endif // _SINGLETON_H_
test_singleton.cc test_singleton.cc
#include "singleton.h"
#include <iostream>
class Log {
public:
void log() {
std::cout << "log" << std::endl;
}
};
int main() {
Log & logger = Singleton<Log>::getInstance();
logger.log();
}
And my g++ statement is而我的 g++ 声明是
g++ -std=c++14 -pthread -o test test_singleton.cc
Error message:错误信息:
/tmp/ccoxQBXl.o: In function `Singleton<Log>::getInstance()':
test_singleton.cc:(.text._ZN9SingletonI3LogE11getInstanceEv[_ZN9SingletonI3LogE11getInstanceEv]+0x2c): undefined reference to `Singleton<Log>::init_flag_'
test_singleton.cc:(.text._ZN9SingletonI3LogE11getInstanceEv[_ZN9SingletonI3LogE11getInstanceEv]+0x38): undefined reference to `Singleton<Log>::val_'
/tmp/ccoxQBXl.o: In function `Singleton<Log>::init()':
test_singleton.cc:(.text._ZN9SingletonI3LogE4initEv[_ZN9SingletonI3LogE4initEv]+0x11): undefined reference to `Singleton<Log>::val_'
collect2: error: ld returned 1 exit status
Finally got it.终于明白了。 The only problem is I didn't initialize the static variables.
唯一的问题是我没有初始化 static 变量。 For C++17, inline keyword allows initialization within class.
对于 C++17,inline 关键字允许在 class 内进行初始化。
#ifndef SINGLETON_H_
#define SINGLETON_H_
#include <boost/noncopyable.hpp>
#include <mutex>
template<typename T>
class Singleton : boost::noncopyable {
public:
Singleton() = delete;
static T& getInstance() {
std::call_once(init_flag_, &Singleton::init);
return *val_;
}
private:
static void init() {
val_ = new T();
}
private:
static inline std::once_flag init_flag_{};
static inline T* val_ = nullptr;
};
#endif // SINGLETON_H_
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.