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

4

5 回答 5

3

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

enum Nationality
{
   ROMANIAN,
   AMERICAN,
   RUSSIAN,
};

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

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

于 2013-08-30T06:43:24.617 回答
1

听起来m_nationalityName应该放在你的基类person中。对我来说,国籍更像是一个属性person。只是不要这样做,static因为您不想让所有的人都拥有相同的国籍。

于 2013-08-30T06:41:42.520 回答
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.
}
于 2013-08-30T06:37:22.890 回答
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);
       }

   };
于 2013-08-30T07:05:10.057 回答
0

使用Curiously recurring 模板模式,您可以这样做:

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

于 2013-08-30T07:10:06.200 回答