从继承的类实例中调用静态成员

时间:2013-03-30 20:02:26

标签: c++ static static-methods static-members

我有两个类YXY拥有一些静态成员 - 我试图通过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提供的内存块}。

我不确定这是否是我尝试做的最好的方法,但是到目前为止我想到的是一种最优雅的方式。任何想法都非常受欢迎。

2 个答案:

答案 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);