简体   繁体   English

C++ 实现模板 Singleton class 时出现链接错误

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM