C++定义静态成员的正确方法
我试图在普通成员函数中使用静态成员。但是编译器报告了一些错误。请看一下这个代码C++定义静态成员的正确方法,c++,C++,我试图在普通成员函数中使用静态成员。但是编译器报告了一些错误。请看一下这个代码 #include <memory> template<typename T> class MyClass { private: static std::allocator<T> alloc; T *p; public: void assign(T e) { p = alloc.allocate(1); alloc.construct(p, e);
#include <memory>
template<typename T>
class MyClass {
private:
static std::allocator<T> alloc;
T *p;
public:
void assign(T e) {
p = alloc.allocate(1);
alloc.construct(p, e);
}
};
我就是这样使用它的:
#include 'myclass.h'
int main() {
MyClass<int> cls;
cls.assign(4);
};
编译器会给出以下错误:
/Users/liuziqi/CLionProjects/cpplearning/src/tt.h:17:9: warning: instantiation of variable 'MyClass<int>::alloc' required here, but no definition is available [-Wundefined-var-template]
p = alloc.allocate(1);
^
/Users/liuziqi/CLionProjects/cpplearning/src/main.cpp:49:7: note: in instantiation of member function 'MyClass<int>::assign' requested here
cls.assign(4);
^
/Users/liuziqi/CLionProjects/cpplearning/src/tt.h:13:28: note: forward declaration of template entity is here
static std::allocator<T> alloc;
^
/Users/liuziqi/CLionProjects/cpplearning/src/tt.h:17:9: note: add an explicit instantiation declaration to suppress this warning if 'MyClass<int>::alloc' is explicitly instantiated in another translation unit
p = alloc.allocate(1);
我不知道哪个部分是错的……我已经定义了静态成员和任何成员函数都应该能够使用它。此错误是否与模板相关?我刚刚学习了模板,不确定是否正确使用了它 除了回答“如何修复”这个问题之外,我还将尝试描述警告所指的内容,这个问题以前肯定已经回答过很多次了
因为MyClass是一个模板,编译器希望模板类的所有代码都可以在同一个文件MyClass.h中使用。由于您只在myclass.h中声明而没有定义alloc,因此编译器假定您犯了错误。它不是绝对需要存在的,因此是警告而不是错误,如果在其他地方定义变量,可以禁用警告,但几乎可以肯定这只是一个错误
如果您使用的是c++17,处理此问题的最简单方法是将静态成员声明为内联,因此它将在此处定义:
static inline std::allocator<T> alloc;
直播:我对这里的“声明”和“定义”有点困惑。我认为我在类模板中对alloc的声明已经是一个“定义”,因为这是我通常定义类成员的方式。为什么还需要在外部定义它?它看起来和我在模板中的“声明”一样……这里有什么不同。这是模板的问题吗?换句话说,如果我们不是在编写模板,而是在这里编写一个类,那么类内部的定义应该是足够的静态变量只在每个类中定义一次,而不是在每个对象中定义一次。在C++17之前,这需要类定义之外的静态成员定义。如果您熟悉的话,这与extern在非类环境中的工作方式非常相似。如果不是在模板的情况下,在另一个文件中定义一个.cpp文件是很正常的,但是由于需要为类的每个实例化定义静态变量,MyClass需要一个,MyClass需要一个不同的,等等。。。然后,该定义将出现在.h文件中,这样实例化的调用方就可以生成代码,为正在使用的模板类的确切实例化类型创建静态成员。
template<typename T>
std::allocator<T> MyClass<T>::alloc;