子类的专用模板

时间:2015-12-04 04:58:29

标签: c++ templates inheritance template-specialization

有一个简单的例子,有两个相关的问题。源代码 - 3个文件:

parent.h:

#ifndef PARENT_H
#define PARENT_H

using namespace std;
#include <vector>

template <class CHILD_TYPE>
class PARENT
{
    public:
        class CHILD_DATA
        {
        public:
            vector<CHILD_TYPE *> child_ptrs;
            void dump_child_data();
        };
    static CHILD_DATA data;
};

template<class CHILD_TYPE>
void PARENT<CHILD_TYPE>::CHILD_DATA::dump_child_data()
{
    return;
}

#endif  /* PARENT_H */

child.h

#ifndef CHILD_H
#define CHILD_H

#include "parent.h"
using namespace std;

#include <string>
#include <algorithm>
#include <iostream>
#include <iterator>

class SPECIAL_CHILD : public PARENT<SPECIAL_CHILD>
{
    public:
        SPECIAL_CHILD (const string newname = "unnamed") : name (newname) {}
        string name;
};

template<>
void PARENT<SPECIAL_CHILD>::CHILD_DATA::dump_child_data()
{
    for (vector<SPECIAL_CHILD *>::iterator it = child_ptrs.begin(); it != child_ptrs.end(); it++)
    {
        cout << (*it)->name << endl;;
    }
    return;
}

#endif  /* CHILD_H */

的main.cpp

#include <cstdlib>
#include "parent.h"
#include "child.h"

using namespace std;

int main(int argc, char** argv) {

    SPECIAL_CHILD c_a;
    SPECIAL_CHILD c_b("named");
    SPECIAL_CHILD c_c("named_again");
    c_a.data.dump_child_data();
    return 0;
}

问题1:此示例未构建:

  

main.cpp:12:对'PARENT :: data&#39;

的未定义引用

为什么呢?父成员的名为data是公共的,我不能从子类对象中作为自己的成员访问它吗?

问题2 :如何在子类的超类专用模板中创建 - 在我的例子中,模板参数是指向子类对象的指针?我绝对不希望超类知道关于子类的任何信息。我应该像我一样将专用模板定义放在子类标题中吗?或者甚至可能在子类.cpp中,如果存在?

感谢。

2 个答案:

答案 0 :(得分:0)

对于Q1,由于datastatic成员,我认为您需要像以下一样访问它:

PARENT<SPECIAL_CHILD>::data.dump_child_data();

答案 1 :(得分:0)

问题1: 将此行添加到您的一个cpp 文件 parent.h

template <class CHILD_TYPE>
typename PARENT<CHILD_TYPE>::CHILD_DATA PARENT<CHILD_TYPE>::data;

- 编辑 -

来自N3797,第14.5.1.3条

  

静态数据成员或静态数据成员模板的定义可以在包含静态成员类模板定义的命名空间范围内提供。

- 结束编辑 -

<击> 问题2:你的意思是?

class SPECIAL_CHILD : public PARENT<SPECIAL_CHILD*>
{
public:
    SPECIAL_CHILD (const string newname = "unnamed") : name (newname) {}
    string name;
};

<击>