2013-01-22 127 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

相關問題