C++ 使用CRTP作为C+中抽象静态方法的替代方法+;11
我正在尝试实现一个通用资源管理器,它将确保每个资源在C++11中只加载一次 我的第一次尝试: resourcemanager.hC++ 使用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
#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"