如何将类传递给方法,并从基类检测继承器?

时间:2011-12-16 08:02:00

标签: c++ class inheritance

很难准确解释我想在这里做什么,但我有一个基类和两个继承这个基类的类。继承它的两个类都有自己独特的成员。我希望能够将两者都传递给方法,并让该方法检测它是什么,然后访问它们的唯一成员。我不能假设只有两个类继承它,所以我正在寻找更通用的解决方案。

以下是我想做的一个例子:

#include <iostream>

class Base {

  public:
    int _type;
    Base() { }
};

class First : public Base {
  public:
    int _first_only;

    First() { }
};

class Second : public Base {
  public:
    int _second_only;

    Second() { }
};

void test (Base b) {

  std::cout << "Type: " << b._type << std::endl;

  if(b._type==1) {
    std::cout << "First\n";
    // Want to be able to do this
    std::cout << "Val: " << (First)b._first_only << std::endl; 
  } else if(b._type==2) {
    std::cout << "Second\n";
    // And this
    std::cout << "Val: " << (Second)b._second_only << std::endl;
  }
}

int main() {

  First f;
  f._first_only=1;
  f._type=1;
  Second s;
  s._type=2;
  s._second_only=2;

  test(f);
  test(s);
}

4 个答案:

答案 0 :(得分:1)

  1. virtual
  2. 中声明Base功能
  3. 将公共成员类型从FirstSecond移至Base
  4. 针对您的具体问题,第二个选项更好:

    class Base {
      public:
        int _member;  // have getter() method, if '_member' is private
        Base() { }
    };
    

    内部,test()

    void test (Base &b) {  // <--- practice to pass by reference if copy is not needed
      // use b._member;
    };
    

答案 1 :(得分:1)

您的代码不能以多态方式工作,因为您通过值传递函数参数,这会导致切片。

如果你有一个为不同类型做不同事情的方法,可以考虑为每种类型重载它。

答案 2 :(得分:1)

这与其他答案类似:

  1. 您可以使用虚函数编写多态类来获取此行为。
  2. 通过指针或引用传递Dervied类对象以获取多态行为。否则会导致对象切片。您的test()函数会导致对象切片。
  3. 此代码也可能对您有所帮助。您可以看到有不同的方法来打印该类型。我使用了GetBaseType(),GetDerivedType()和GetType()。其中GetType()方法对你来说很方便。为方便起见,有两个构造函数。构造函数允许初始化数据成员。

    class Base {
    private:
        int _type;
    public:
        Base(int type) : _type(type) { }
        int GetBaseType() { return _type; }
        virtual int GetDerivedType() = 0;
        virtual int GetType() { return _type; }
    };
    
    class First : public Base {
    private:
        int _first_only;
    public:
        First() : Base(1), _first_only(1) { }
        First(int first_only) : Base(first_only), _first_only(first_only) { }
        int GetDerivedType() { return _first_only; }
        virtual int GetType() { return _first_only; }
    };
    
    class Second : public Base {
    private:
        int _second_only;
    public:
        Second() : Base(2), _second_only(2) { }
        Second(int second_only) : Base(second_only), _second_only(second_only) { }
        int GetDerivedType() { return _second_only; }
        virtual int GetType() { return _second_only; }
    };
    
    void test (Base &b) {
        std::cout << "Type: " << b.GetBaseType() << std::endl;
        std::cout << "Type: " << b.Base::GetType() << std::endl;
    
        std::cout << "Dervied type: \n";
        std::cout << "Val: " << b.GetDerivedType() << std::endl; 
        std::cout << "Val: " << b.GetType() << std::endl; 
    }
    
    int main() {
    
      First f(1);
      Second s(2);
    
      test(f);
      test(s);
    
      First f1;
      Second s1;
    
      test(f1);
      test(s1);
    }
    

答案 3 :(得分:0)

我要做的三件事:

  • 通常,切换类型代码不被视为良好的面向对象设计:而是将切换代码拉入类中。
  • 我还在特定类的构造函数中设置了类型标记。
  • 正如其他人提到的那样,你需要通过引用来传递参数以避免切片。

这是代码的样子:

#include <iostream>

class Base {

  public:
     int _type;
     Base() { }
     virtual void print_to_stream( std::ostream & os ) const =0;
};

class First : public Base {
  public:
    int _first_only;

    First() {  _type =1; }
    void print_to_stream( std::ostream & os ) const
    {
       os<<"First\n";
       os<<"Val: " << _first_only << std::endl;
    }
};

class Second : public Base {
  public:
    int _second_only;

    Second() { _type=2; }

    void print_to_stream( std::ostream & os ) const
    {
      os << "Second\n";
      os << "Val: " << _second_only << std::endl;
    }
};

void test (Base & b)
{
  std::cout << "Type: " << b._type << std::endl;
  b.print_to_stream( std::cout );
}

int main() {
  First f;
  f._first_only=1;
  Second s;
  s._second_only=2;

  test(f);
  test(s);
}