我有两个类Y
和X
,Y
拥有一些静态成员 - 我试图通过X
实例访问:
template <class T>
class Y {
public:
Y() {
i = 0;
v = std::vector<int>(10, 10);
}
static int value() {
return v[i];
}
private:
static int i;
static std::vector<int> v;
};
class X : public Y<X> {
public:
X() {
}
};
int main() {
X *x(new X());
std::cout << x->value() << std::endl;
}
即使它编译,它也没有正确链接:
$ g++ t.cpp
/tmp/ccB4ijzw.o: In function `Y<X>::Y()':
t.cpp:(.text._ZN1YI1XEC2Ev[Y<X>::Y()]+0x11): undefined reference to `Y<X>::i'
t.cpp:(.text._ZN1YI1XEC2Ev[Y<X>::Y()]+0x4a): undefined reference to `Y<X>::v'
/tmp/ccB4ijzw.o: In function `Y<X>::value()':
t.cpp:(.text._ZN1YI1XE5valueEv[Y<X>::value()]+0x6): undefined reference to `Y<X>::i'
t.cpp:(.text._ZN1YI1XE5valueEv[Y<X>::value()]+0x10): undefined reference to `Y<X>::v'
collect2: ld returned 1 exit status
上下文(如果重要):
我正在尝试编写一个内存管理器 - class Y
- 静态保存一个内存池,以便class X
的所有实例都使用Y
提供的内存块}。
我不确定这是否是我尝试做的最好的方法,但是到目前为止我想到的是一种最优雅的方式。任何想法都非常受欢迎。
答案 0 :(得分:3)
必须定义和声明静态数据成员。如果这是一个普通的课程,你可以这样做:
// header:
class C {
static int i;
};
// source:
int C::i = 3;
使用类模板通常不会将代码放在源文件中,所以你要这样做:
// header:
template <class T>
class C {
static int i;
};
template <class T>
int C<T>::i = 3;
答案 1 :(得分:1)
由于函数value
是静态的,因此class Y
的所有实例都是通用的。调用静态成员函数的方法就像
std::cout << Y<X>::value() << std::endl;
不是(这不是非法的,但这不是一个好习惯。为什么要使这个功能保持静态我还是要这样做?)
std::cout << x->value() << std::endl;
此外,您必须定义所有静态成员。像
这样的东西template <class T>
int Y<T>::i = 0;
template <class T>
std::vector<int> Y<T>::v(0);