C++ 使用CRTP作为C+中抽象静态方法的替代方法+;11

C++ 使用CRTP作为C+中抽象静态方法的替代方法+;11,c++,c++11,crtp,C++,C++11,Crtp,我正在尝试实现一个通用资源管理器,它将确保每个资源在C++11中只加载一次 我的第一次尝试: resourcemanager.h #ifndef RESOURCEMANAGER_H #define RESOURCEMANAGER_H #include <map> #include <memory> template<typename T> class ResourceManager { public: static std::shared_pt

我正在尝试实现一个通用资源管理器,它将确保每个资源在C++11中只加载一次

我的第一次尝试:

resourcemanager.h

#ifndef RESOURCEMANAGER_H
#define RESOURCEMANAGER_H

#include <map>
#include <memory>


template<typename T>
class ResourceManager {

public:
    static std::shared_ptr<T> load(std::string filePath);

private:
    static map<std::string, std::weak_ptr<T>> resources;
    virtual static std::shared_ptr<T> loadResource(std::string filePath) = 0;
};

#endif // RESOURCEMANAGER_H

#include "resourcemanager.h"
#ifndef RESOURCEMANAGER_H
#define RESOURCEMANAGER_H

#include <map>
#include <memory>

template<typename T, class Derived>
class ResourceManager {

public:
    static std::shared_ptr<T> load(std::string filePath);

private:
    static std::map<std::string, std::weak_ptr<T>> resources;
    static std::shared_ptr<T> loadResource(std::string filePath);
};

#endif // RESOURCEMANAGER_H
#ifndef MANAGEDSTRING_H
#define MANAGEDSTRING_H

#include "resourcemanager.h"

class ManagedString {

public:
    ManagedString(std::string filePath);
    std::string get();

private:
    std::shared_ptr<std::string> ptr;

    class StringManager : public ResourceManager<std::string, StringManager> {
    private:
        static std::shared_ptr<std::string> loadResource(std::string filePath);
    };
};

#endif // MANAGEDSTRING_H
这样行吗?这是编译器的缺点吗?还是我想做一些我不该做的事

我也考虑过改变我的设计,不过我觉得没那么糟糕。在这一点上,请随意与我提出不同意见。

在resourcemanager.h中,这一行:

#include "resourcemanager.h"
应该是:

#include "resourcemanager.cpp"
这似乎只适用于您的第一个示例,但同样适用于所有其他示例。

否则,也可以将模板类的声明和定义放在同一个文件中。

Wow,我怀疑这可能很简单。但我没想到会那么愚蠢。谢谢@法尔比不客气,我甚至还没读完整的答案,就试了一下。很好,我很高兴能提供帮助。澄清一下:问题是我没有在头文件中声明我的函数。据我所知,在使用模板时,所有函数都需要在头文件中声明。
#include "managedstring.h"

using namespace std;

ManagedString::ManagedString(string filePath) {
    ptr = StringManager::load(filePath);
}

string ManagedString::get() {
    return *ptr;
}

shared_ptr<string> ManagedString::StringManager::loadResource(string filePath) {
    // dummy implementation
    return make_shared<string>("foo");
}
#include <iostream>
#include "managedstring.h"

using namespace std;

int main() {
    ManagedString string1 = ManagedString("bar");
    ManagedString string2 = ManagedString("foobar");
    cout << string1.get() << endl; 
    cout << string2.get() << endl; 
}
/tmp/ccgqljOQ.o: In function `ManagedString::ManagedString(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
managedstring.cpp:(.text+0xdd): undefined reference to `ResourceManager<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >,
 ManagedString::StringManager>::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
#include "resourcemanager.h"
#include "resourcemanager.cpp"