2013-01-22 163 views
0

我有以下情形:基类的方法访问派生类成员

class num { 
    public: 
    void print(ostream* o); // Prints the n variable 
}; 

class int_num : public num{ 
    public: 
    int n; // Initialized by this class's constructor 
}; 

class float_num : public num{ 
    public: 
    float n; // Initialized by this class's constructor 
}; 

class double_num : public num{ 
    public: 
    double n; // Initialized by this class's constructor 
}; 

如何实现这样的方案

回答

4

给它一个虚方法,在派生类中实现:

class num { 
public: 
    void print(ostream& o) const 
    { // Prints the n variable 
     doPrint(o); 
    } 
private: 
    virtual void doPrint(ostream& os) const = 0; 
}; 

class double_num : public num{ 
    public: 
    double n; // Initialized by this class's constructor 
private: 
    void doPrint(ostream& os) const 
    { 
    os << n; 
    } 
}; 
+0

@MikeSeymour对,我在想一个不同的问题的。我编辑了出来。 – juanchopanza

+1

拥有公共印刷和私人纯虚拟doPrint而不是单个公共纯虚拟印刷(或doPrint)有什么优势? – undu

0

有两种解决方案。首先是使print方法成为纯抽象方法,并在所有子类中实现它。二是使用模板:

template<typename T> 
class num 
{ 
public: 
    void print(std::ostream& os) const 
     { 
      os << num_; 
     } 

private: 
    T num_; 
}; 

typedef num<float> float_num; 
typedef num<int>  int_num; 
2

为什么不使用template

template<typename T> 
class num 
{ 
    T n; //data of type T 

public: 

     //add constructor(s) to initialize n 

     void print(std::ostream &out) { out << n ; } 

     //add functions(s) to work with n 
}; 

可以做印刷。

现在你有两个选择:

  • 使用typedef如果一切都在你的代码的派生类型都在做同样的事情,没有什么类型特定:

    //use typedefs 
    typedef num<int> int_num; 
    typedef num<float> float_num; 
    typedef num<double> double_num; 
    
  • 或者使用继承如果您需要做的类型派生类中的具体事物:

    class int_num : public num<int> 
    { 
        //int specific things 
    }; 
    

的一点是,num<T>可以做印刷,不论你是否使用typedef继承

1

你有两种选择。

其中之一是使print()纯虚拟并在派生类中实现它,正如其他人已经指出的那样。

另一种选择是使用Curiously recurring template pattern,就像这样:

template <typename Impl> 
class num 
{ 
public: 
    void print(ostream &os) const 
    { 
    os << static_cast<const Impl*>(this)->n; 
    } 
}; 

class int_num : public num<int_num> 
{ 
    //same as before 
}; 

class float_num : public num<float_num> 
{ 
    //same as before 
}; 

//etc. 
+0

我从来没有听说过CRTP的习惯用法。有趣!谢谢 – AndyG

相关问题