访问派生类的属性

时间:2016-05-01 21:06:55

标签: c++ inheritance polymorphism

我有两个从一个基类继承的派生类

<Import Project="$(MSBuildExtensionsPath)\MonoGame\v3.0\MonoGame.Content.Builder.targets" />

Derived_one类包含一个object向量。 我为每个对象定义了克隆函数,这意味着当我将class Base{ public: virtual void Greetings(){ cout << " I am base class " << endl:} virtual string getName(){ return "base"} } class Derived_one : public Base{ public: virtual void Greetings(){ cout << " I am derived one " << endl:} virtual string getName(){ return "one"} private: vector<Base*> m; } class Derived_two : public Base{ public: virtual void Greetings(){ cout << " I am derived two " << endl:} virtual string getName(){ return "two"} private: vector<string> str; } Derived_two推入向量时,它们将保持为Derived并且对象切片不会发生,例如

当我在Derived_one类中声明print函数来打印矢量时,例如

Derived_one

它将很好地打印基于推入的类的结果。(我最后一个对象是Derived_two它将打印&#34;我派生了两个&#34;依此类推。

问题是,当我想在Derived_two类中打印字符串向量时,我将void Derived_one::print(){ for( size_t i = 0; i < m.size(); i++){ m[i] -> Greetings() } } 方法更改为

print

抛出错误

  

&#34;基类没有成员str&#34;

为什么会发生这种错误?该向量不应该从Base类继承。有没有办法解决它?感谢。

2 个答案:

答案 0 :(得分:2)

您可以使用castcast Base个对象Derived_two来访问Derived_two属性。您还需要strpublic或向其提供公共获取者(或使用friend)...

但是在这里使用cast肯定证明你的设计很糟糕。您应该使用virtual函数使每个派生类专门化Base类。不要使用类名(getName())来区分对象......

如下:

class Base{
   public:
       virtual void Greetings(){ cout << " I am base class " << endl:}
       virtual string getName(){ return "base"}
       virtual vector<string>* getStr() { return NULL; }
};
class Derived_one : public Base{
   public:
       virtual void Greetings(){ cout << " I am derived one " << endl:}
       virtual string getName(){ return "one"}
   private:
  vector<Base*> m;
};
class Derived_two : public Base{
   public:
      virtual void Greetings(){ cout << " I am derived two " << endl:}
      virtual string getName(){ return "two"}
      virtual vector<string>* getStr() { return &str; }
   private:
  vector<string> str;
};

然后做:

for( size_t i = 0; i < m.size() ; i++){
   if( m[i]->getStr() ){
       // that's a Derived_two object, a vector<string> attribue is available
       for( size_t j = 0; j < m[i]->getStr()->size() ; j++){
           cout << (*(m[i]->getStr()))[j] << endl;
       }
   } else [
       // that's a Derived_one or a Base object, no vector<string> is available
   }

   cout << m[i] ->getName() << endl;
}

如果您从未创建任何Base个对象,则可以通过将getStr()添加为纯虚函数来使该类抽象化:

class Base{
       public:
           virtual void Greetings(){ cout << " I am base class " << endl:}
           virtual string getName(){ return "base"}
           virtual vector<string>* getStr() = 0;
    };
    class Derived_one : public Base{
       public:
           virtual void Greetings(){ cout << " I am derived one " << endl:}
           virtual string getName(){ return "one"}
           virtual vector<string>* getStr() { return NULL; }
       private:
      vector<Base*> m;
    };
    class Derived_two : public Base{
       public:
          virtual void Greetings(){ cout << " I am derived two " << endl:}
          virtual string getName(){ return "two"}
          virtual vector<string>* getStr() { return &str; }
       private:
      vector<string> str;
    };

答案 1 :(得分:0)

在您的代码中,m[i]的类型为Base*,因此您需要明确地从Base转发到Derived_two才能访问仅在Derived_two中知道的成员{1}}:

for( size_t i = 0; i < m.size() ; i++){
    if( m[i] -> getName() == "two" ){
        Derived_two * d = static_cast<Derived_two*>(m[i]);
        for( size_t j = 0; j < d -> str.size() ; j++){
            cout << d ->str[j] << endl;
        }
    }
    cout << m[i] ->getName() << endl;
}