首页 文章

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

提问于
浏览
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”方法,但我认为这不是解决此问题的正确方法 .

5 回答

  • 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

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

    enum Nationality
    {
       ROMANIAN,
       AMERICAN,
       RUSSIAN,
    };
    
    class Person
    {
       Nationality nationality; // or std::vector<Nationality> nationalities;
    };
    

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

  • 0

    听起来像 m_nationalityName 应该放在你的基类 person 中 . 对我而言,国籍更像是 person 的一个属性 . 只是不要成为 static 因为你不想让所有人拥有相同的国籍 .

  • 1

    我认为这种情况可以像这样处理 . 因为不同的国籍只是有不同的名称,没有不同的行为,所以不需要使用多态

    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);
           }
    
       };
    
  • 3

    使用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[] .

相关问题