首页 文章

继承c中的模板类

提问于
浏览
75

假设我们有一个模板类 Area ,它有一个成员变量 T area ,一个 T getArea() 和一个 void setArea(T) 成员函数 .

我可以通过键入 Area<int> 来创建特定类型的 Area 对象 .

现在我有一个继承 Area 类的 Rectangle 类 . 由于 Rectangle 本身不是模板,因此我无法输入 Rectangle<int> .

如何为 Rectangle 对象专门继承 Area 类型?

编辑:对不起,我忘了澄清 - 我的问题是是否可以继承区域而不专门化它,因此它不会作为整数区域继承,但区域矩形可以专门化类型 .

6 回答

  • 182
    #include<iostream>
    
    using namespace std;
    
    template<class t> 
    class base {
    protected:
        t a;
    public:
        base(t aa){
            a = aa;
            cout<<"base "<<a<<endl;
        }
    };
    
    template <class t> 
    class derived: public base<t>{
        public:
            derived(t a): base<t>(a) {
            }
            //Here is the method in derived class 
        void sampleMethod() {
            cout<<"In sample Method"<<endl;
        }
    };
    
    int main() {
        derived<int> q(1);
        // calling the methods
        q.sampleMethod();
    }
    
  • 8

    为了理解模板,将术语直截了当是非常有利的,因为你谈论它们的方式决定了思考它们的方式 .

    具体来说, Area 不是模板类,而是类模板 . 也就是说,它是一个可以从中生成类的模板 . Area<int> 就是这样一个类(它不是一个对象,但当然你可以用与从任何其他类创建对象相同的方式从该类创建一个对象) . 另一个这样的课将是 Area<char> . 请注意,这些是完全不同的类,除了它们是从同一个类模板生成的事实之外没有任何共同之处 .

    由于 Area 不是类,因此无法从中派生类 Rectangle . 您只能从另一个类(或其中几个)派生一个类 . 由于 Area<int> 是一个类,因此您可以从中派生 Rectangle

    class Rectangle:
      public Area<int>
    {
      // ...
    };
    

    由于 Area<int>Area<char> 是不同的类,您甚至可以同时从两个类派生(但是当访问它们的成员时,您将不得不处理歧义):

    class Rectangle:
      public Area<int>,
      public Area<char>
    {
      // ...
    };
    

    但是,您必须指定在定义 Rectangle 时从哪个类派生 . 无论这些类是否是从模板生成,都是如此 . 同一类的两个对象根本不能具有不同的继承层次结构 .

    你可以做的是使 Rectangle 也成为一个模板 . 如果你写

    template<typename T> class Rectangle:
      public Area<T>
    {
      // ...
    };
    

    你有一个模板 Rectangle ,你可以从中获得一个派生自 Area<int> 的类 Rectangle<int> ,以及一个派生自 Area<char> 的不同类 Rectangle<char> .

    可能你想拥有一个单一类型 Rectangle ,这样你就可以将各种 Rectangle 传递给同一个函数(它本身不需要知道Area类型) . 由于通过实例化模板 Rectangle 生成的 Rectangle<T> 类在形式上彼此独立,因此它不起作用 . 但是,您可以在此处使用多重继承:

    class Rectangle // not inheriting from any Area type
    {
      // Area independent interface
    };
    
    template<typename T> class SpecificRectangle:
      public Rectangle,
      public Area<T>
    {
      // Area dependent stuff
    };
    
    void foo(Rectangle&); // A function which works with generic rectangles
    
    int main()
    {
      SpecificRectangle<int> intrect;
      foo(intrect);
    
      SpecificRectangle<char> charrect;
      foo(charrect);
    }
    

    如果您的泛型 Rectangle 从通用 Area 派生很重要,那么您也可以使用 Area 执行相同的操作:

    class Area
    {
      // generic Area interface
    };
    
    class Rectangle:
      public virtual Area // virtual because of "diamond inheritance"
    {
      // generic rectangle interface
    };
    
    template<typename T> class SpecificArea:
      public virtual Area
    {
      // specific implementation of Area for type T
    };
    
    template<typename T> class SpecificRectangle:
      public Rectangle, // maybe this should be virtual as well, in case the hierarchy is extended later
      public SpecificArea<T> // no virtual inheritance needed here
    {
      // specific implementation of Rectangle for type T
    };
    
  • 14

    使Rectangle成为模板并将typename传递给Area:

    template <typename T>
    class Rectangle : public Area<T>
    {
    
    };
    
  • 7

    你只是想从 Area<int> 派生出来吗?在这种情况下,你这样做:

    class Rectangle : public Area<int>
    {
        // ...
    };
    

    编辑:在澄清之后,似乎你实际上也试图使 Rectangle 模板,在这种情况下,以下应该工作:

    template <typename T>
    class Rectangle : public Area<T>
    {
        // ...
    };
    
  • 6

    Rectangle 必须是模板,否则它只是一种类型 . 它不可能是非模板,而它的基础是神奇的 . (它的基础可能是模板实例化,但您似乎希望将基础功能保留为模板 . )

  • 0
    class Rectangle : public Area<int> {
    };
    

相关问题