2013-08-30 150 views
1

我有一個基類和幾個可以有多個實例的派生類。 派生類有一個靜態字符串,其中存儲國籍名稱。 看起來像這樣...實現基類方法來訪問派生類的屬性

// Base Class 
class Person{ 
    private: 
     // Informations that every person has. Not depending on the nationality 
     unsigned char m_size; 
     char[] m_name; 

    public: 
     // Get the human readable name of a nationality 
     void getNationalityName(char* pNatiName); 
} 

void Base::getNationalityName(char* pNatiName); 
{ 
    strcpy(pNatiName, m_nationalityName); 
} 


// A derived class 
class American : public Person{ 
    private: 
     unsigned int m_dollar; 
     static char[] m_nationalityName; 
} 

// Another derived class 
class Russian : public Person{ 
    private: 
     unsigned int m_rubel; 
     static char[] m_nationalityName; 
} 

現在,我想從一個派生類的方法「getNationalityName」訪問國籍的名字。 問題是,基類不知道派生類具有名爲「m_nationalityName」的屬性。

我可以在每個類中實現「getNationalityName」方法,但我認爲這不是解決此問題的正確方法。

回答

1

使用多態性。使你的getNationalityName函數virtual,並重新定義它在派生類中返回所需的字符串。每一次,派生類的函數將被調用,返回相應的類的字符串:

//base class: 
class Person{ 
    <...> 

    public: 
     virtual void getNationalityName(char* pNatiName); 
} 

<...> 

// A derived class 
class American : public Person{ 
    public: 
     void getNationalityName(char* pNatiName) 
     { 
      strcpy(pNatiName, m_nationalityName); 
     } 
    private: 
     unsigned int m_dollar; 
     static char[] m_nationalityName; 
} 

<...> 

int main() 
{ 
    Person * p = new American(); 
    p->getNationalityName(<...>); // calls American::getNationalityName name even though p is a pointer to the base class. 
} 
+0

似乎是一個不錯的解決方案。謝謝:) – Praind

1

聽起來m_nationalityName應該在你的基類person放。對我而言,國籍更像是person的屬性。只是不要讓它static,因爲你不想讓所有的人都有相同的國籍。

+0

是的,我也在想那個...但是那麼所有的人都會有相同的國籍名稱嗎?或者每個派生類都會有一個新的靜態屬性實例? – Praind

+0

@ user2674795你是對的,這是不正確的。 –

+0

@ user2674795,好點。更新! –

3

不要。設計看起來有缺陷。國籍應該是一個人的財產(即數據成員)。如果某人有兩個國籍怎麼辦?

enum Nationality 
{ 
    ROMANIAN, 
    AMERICAN, 
    RUSSIAN, 
}; 

class Person 
{ 
    Nationality nationality; // or std::vector<Nationality> nationalities; 
}; 

枚舉值可以很容易轉換後。

+0

我認爲OP想要一個字符串表示來打印出來,或者類似的東西... – SingerOfTheFall

+1

@SingerOfTheFall後續的轉換是微不足道的。我的主要觀點是沒有那個階級層次。 –

+0

是的,這是真的。這也只是一個例子,在我的情況下,沒有人可以擁有兩個國籍,對於混淆抱歉:) – Praind

0

我認爲這種情況可以這樣做。因爲不同的國籍只是有不同的名稱,而不是不同的行爲,所以不需要使用多態性

class Nationality 
    { 
    private: 
     Nationality(const char* name_i):m_name(name_i) 
     { 
     } 
     const char * m_name; 
    public: 
     static Nationality& American() 
     { 
      static Nationality country("American"); 
      return country; 
     } 

     static Nationality& Russian() 
     { 
      static Nationality country("Russia"); 
     } 

     void getName(char* pNatiName) const 
     { 
      strcpy(pNatiName, m_name); 
     } 

    }; 


    class Person 
    { 
    private: 
     <................> 
     Nationality* nationality 

    public: 
     void getNationalityName(char* pNatiName)const 
     { 
      nationality->getName(pNatiName); 
     } 

    }; 
0

隨着Curiously recurring template pattern,你可以這樣做:

template<class T> 
class Person { 
    static const std::string m_nationalityName; 

    // ... 
}; 

template<class T> const std::string Person<T>::m_nationalityName = "Unknown"; 

class American : public Person<American> { 
    // ... 
}; 

template<> const std::string Person<American>::m_nationalityName = "American"; 

class Russian : public Person<Russian> { 
    // ... 
}; 

template<> const std::string Person<Russian>::m_nationalityName = "Russian"; 

不能與char[]工作。

+0

-1對於給定的問題,這不是一個好的解決方案,因爲美國人不再是個人了。其次,它完全與char [] – Sebastian

+0

一起使用,我嘗試使用'char []',它不會編譯,因爲字符串具有不同的長度。我不明白美國人不再是一個人了。 – flyx

+0

美國人不是一個人,它是一個人。你沒有多態的Person基類了。 – Sebastian

相關問題