如何从专门用于自身的模板派生类?

时间:2012-01-29 15:33:24

标签: c++ templates

我真的不知道如何描述这个,但这是代码:

class A : public std::vector<A>
{
};

//....

A a;
a.push_back(a);

它做了什么以及为什么要这样做?

3 个答案:

答案 0 :(得分:4)

这是 curiously recurring template pattern(CRTP) 它允许您实现静态多态

但是,使用std::vector作为基类是不好的做法,因为它没有虚拟析构函数。

答案 1 :(得分:1)

由于它是A s而不是A* s的向量,a本身不能包含它自己。但是,push_back会在调用时将a的副本添加到向量中。

示例:

#include <vector>
#include <iostream>
using namespace std;
class A : public std::vector<A>
{
    public:
        void print(int level=0){
            for (int i=0;i<level;i++) cout<<"  ";
            cout << "0x" << hex << (unsigned int)this << "=[";
            if (size()){
                cout  << endl;
                for (int i=0; i<size(); i++)
                    (*this)[i].print(level+1);
                for (int i=0;i<level;i++) cout<<"  ";
            }
            cout <<"]"<<endl;
            if(!level) cout << endl;
        }

};

int main(){
    A a;
    for (int i=1;i<=3;i++){
        a.push_back(a);
        a.print();
    }
    return 0;
}

输出:

0xbff4fa20=[
  0x9ec2008=[]
]

0xbff4fa20=[
  0x9ec2018=[]
  0x9ec2024=[
    0x9ec2038=[]
  ]
]

0xbff4fa20=[
  0x9ec2048=[]
  0x9ec2054=[
    0x9ec20a0=[]
  ]
  0x9ec2060=[
    0x9ec2080=[]
    0x9ec208c=[
      0x9ec2008=[]
    ]
  ]
]

答案 2 :(得分:0)

子类是终止泛型。向量只能包含A类型的对象,而不能包含任意向量。

现在,为什么要构建一个包含自身的对象,我知道。但有理由这样做。例如,对于单元测试,要确保算法能够处理包含循环的集合。一个朴素的算法可能会遇到一个无限循环,因此无法进行单元测试。