实现基类方法来访问派生类的属性

时间:2013-08-30 06:33:59

标签: c++ class oop inheritance

我有一个基类和几个可以有多个实例的派生类。 派生类具有静态字符串,其中存储了国籍名称。 看起来像这样......

// 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”方法,但我认为这不是解决此问题的正确方法。

5 个答案:

答案 0 :(得分:3)

别。设计看起来有缺陷。国籍应该是一个人的财产(即数据成员)。如果某人有两个国籍怎么办?

enum Nationality
{
   ROMANIAN,
   AMERICAN,
   RUSSIAN,
};

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

之后可以轻松转换枚举值。

答案 1 :(得分: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.
}

答案 2 :(得分:1)

m_nationalityName之类的声音应该放在您的基类person中。对我而言,国籍更像是person的属性。只是不要让它static,因为你不想让你的所有人拥有相同的国籍。

答案 3 :(得分: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);
       }

   };

答案 4 :(得分: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[]