C++:如何使<T>模板化类的每个 T 的所有实例的 std::vector 静态?
C++: How to make std::vector<T> static for all instances of every T of a templated class?
我有点不确定这个问题的标题是否可以阅读,但我不知道该如何提出。
所以我有一堂课,我们称其为myclass称为:
template <class T>
class MyClass
{
public:
...
std::vector<T> vecData;
...
void LoadData() {/* Loads data from database into vecData collection */}
}
有点简化,代码用作:
MyClass<Cat> catInstance1;
catInstance1.LoadData();
....
MyClass<Cat> catInstance2;
catInstance2.LoadData();
...
MyClass<Dog> dogInstance1;
dogInstance1.LoadData();
...
MyClass<Dog> dogInstance2;
dogInstance2.LoadData();
...
但是,现在我希望Vecdata集合变得静态,因为该vecdata充满了对象,并且目前是针对每个实例(甚至相同的模板类型(完成的,而实际上,如果我是完美的,如果我是完美的每个模板T型只需加载一次数据。这意味着Catinstance1在调用LoadData((时将加载数据库中的数据,但是当Catinstance2调用相同功能时,它应该能够使用Catinstance1中已加载的数据。然后,同样适用于doginstance1和doginstance2。
因此,我希望Collection Vecdata在类型的每个模板类型中静态(在此示例中(实例化(CAT或DOG(。一个人如何在C 中进行?我最近开始在C 中创建自己的模板类,因此我可以在此特定情况下有所帮助。
谢谢!
编辑:根据JAROD42的评论修复了上面的代码
您只需要将成员声明为静态即可。对于模板的每个参数化,它将存在一个单独的实例。
有关更多详细信息,请参见CAN模板类在C 中具有静态成员。
您可以这样做:
class animal {
...
}
class cat : public animal{
...
}
class dog : public animal {
...
}
class Base {
protected:
static std::vector<animal*> vectData;
}
std::vector<animal*> Base::vectData;
template<clas T>
class MyClass : public Base {
void LoadData();
}
感谢大家的意见,我想我设法自己解决了!这是必须做的。
我有这个课:
template <class T>
class MyClass
{
public:
...
std::vector<T> vecData;
...
void LoadData() {/* Loads data from database into vecData collection */}
};
问题是我需要提供一个仍在标题文件中的静态vecdata Collection 的定义,但在myClass {}范围之外之类
简单下面的代码下方我添加了:
template <typename T>
std::vector<T> MyClass<T>::vecData = {};
这是编译的,并给了我我想要的结果;MyClass与之实例化的每个模板类型的静态集合。太好了!
考虑模板中静态成员的行为
在模板类中,为每个实例化完全推导的模板实例化静态成员,即它们都共享数据的单个实例。
因此,声明向量静态就足够了。
但要注意
...即使共享数据,所有loaddata(( - 调用将重新加载或附加新数据!
请参阅下面的广泛示例!
#include <iostream>
#include <vector>
#include <atomic>
#include <mutex>
template <typename T>
// Simple creator class providing us data
class Creator {
public:
static T Create() {
return T();
}
};
template <>
// Simple creator class providing us data for INTEGER, just counting up from 0 on each call.
class Creator<int> {
static int mCounter;
public:
static int Create() {
return mCounter++;
}
};
// Don't forget to initialize.
int Creator<int>::mCounter = 0;
template <typename T>
// Loader class encapsulating thread-synchronization, "already-loaded"-handling and effective data loading mechanisms...
// Here: Using the Creator<T>
class Loader {
public:
Loader()
: mLoaded(false),
mData() {
}
bool LoadData() {
// Deactivate check, to allow confirming duplicate addition of data from two equally-typed containers! EXAMPLE ONLY
// Uncomment, to have the "load only once" functionality.
// if(mLoaded.load())
// return true;
std::lock_guard<std::mutex> guard(mLoadMutex);
bool loaded = LoadDataImpl();
if(loaded)
mLoaded.store(loaded);
return loaded;
}
const std::vector<T>& ConstData() const { return mData; }
private:
bool LoadDataImpl() {
// Actual data loading. Return true on success. False otherwise.
try {
// Code...
for(int i=0; i<10; ++i) {
mData.push_back(Creator<T>::Create());
}
return true;
} catch(...) { // Actually don't use the ... but specific types.
return false;
}
}
std::mutex mLoadMutex;
std::atomic<bool> mLoaded;
std::vector<T> mData;
};
template <typename T>
// The actual container, using the STATIC loader.
// The Loader<T>-static instance is shared among all Container<T>'s!
class Container {
static Loader<T> mLoader;
public:
bool LoadData() { return mLoader.LoadData(); }
const std::vector<T>& Data() const { return mLoader.ConstData(); }
};
// Don't forget to initialize...
template <typename T>
Loader<T> Container<T>::mLoader = {};
// Example struct
struct Whatever {
int whateverValue;
};
int main() {
Container<int> intContainer;
Container<int> intContainer2;
Container<bool> boolContainer;
Container<Whatever> whateverContainer;
// Load data 0..10 into buffer
if(!intContainer.LoadData()) {
std::cout << "Cannot load data of container 1.n";
} else {
std::cout << "Got C1 data.n";
}
// Load data 11..19 into buffer, IF we have the above check for mLoaded commented.
// Otherwise, nothing will happen here!
if(!intContainer2.LoadData()) {
std::cout << "Cannot load data of container 2.n";
} else {
std::cout << "Got C2 data.n";
}
//
// If we commented the mLoaded-precondition, we will get a print of 0..19 in the console.
// Otherwise 0..9
//
for(const int& v : intContainer2.Data()) {
std::cout << v << "n";
}
std::cout << std::endl;
}
我创建了一个小演示,该演示:
- 声明一个容器
- 使用加载程序(在所有容器之间共享(,因为它是静态的。
- 加载程序将创建者用作虚拟databackend,在每个呼叫中计数0 int-types
这里重要的部分是,加载程序为多线程访问和原子" MLOAD"提供锁定,该锁定器是否已事先检查数据。
由于附加的数据加载逻辑会使容器本身笨拙,因此我将其封装在装载机中,并具有漂亮的单线静态装载机MLOADER。
只需阅读代码和其中的评论即可显得!
- 静态数据成员模板专用化的实例化点在哪里
- 如果 std::vector::clear() 不是静态的,如何在没有实例的情况下调用它?
- C++两个源文件之间共享的枚举的静态实例
- 为什么静态数组成员变量在调用对象的实例后不显示任何内容?
- 如何在没有实例的情况下获取非静态方法的类型?
- 名称隐藏对静态函数继承的实例使用
- 如何正确实例化静态字段 tat 是另一个类对象
- 初始值设定项列表是否足够静态以允许实例化模板?
- 类外的静态变量实例化
- c++ 是否保证标头初始化的静态 const 成员跨编译单元和库共享单个实例?
- 实例成员与静态成员与非类方法的开销
- 生成代码(在编译时)以调用模板的每个实例化的静态函数
- 引用的静态强制转换强制模板实例化,其中不完整的类型很好
- 让类方法为每个实例保存不同的静态变量
- 包含不同大小静态数组的类的多个实例
- 作为成员的静态类模板实例会导致未解析的外部符号错误
- 静态模板成员函数的实例化?
- 为什么可以在没有实例变量的情况下访问静态回调方法中的静态成员变量?
- 我们如何在模板类中使用静态映射,模板类的每个实例化都应该使用相同的映射
- cpp 静态对象实例化