可以将指向子类的指针分配给具有超类类型的varibale吗?

时间:2018-02-23 22:45:47

标签: c++ templates pointers types

假设有一个A类,它有两个子类,Aa和Ab。我想创建一个可以存储指向Aa和Ab类对象的指针的数组。如果使用类A的类型声明数组,这是否有效?如果没有,我该怎么做到这一点?例如:

A *arr;
//space allocated
Ab *obj1;
arr[x] = obj1;

在相关的说明中,我想编写一个函数,当给定一个位置时,将返回存储在数组中该位置的对象。如果以上工作并且我有Aa或Ab的对象数组,则该函数可以返回Aa或Ab类型的对象。如果函数的返回类型指定为A,那么超类是否有效?如果没有,我已经查看了模板函数,但找不到关于返回类型是可变的直接答案,而不是参数。对于此示例,函数的参数始终为int,但它可能返回Aa或Ab,具体取决于数组中该位置的内容。

2 个答案:

答案 0 :(得分:1)

是的,这是virtual methods实现的方式(使用指向基类的指针)和#include <iostream> using namespace std; #include <vector> class A{ public: virtual void foo()const{ std::cout << "A::foo()" << std::endl; } }; class Aa : public A { public: virtual void foo()const{ std::cout << "Aa::foo()" << std::endl; } }; class Ab : public A { public: virtual void foo()const{ std::cout << "Ab::foo()" << std::endl; } }; int main(){ A* ptrA[3]; A* a = new A; Aa* aa = new Aa; Ab* ab = new Ab; ptrA[0] = aa; ptrA[1] = ab; ptrA[2] = a; for(int i(0); i != 3; ++i) ptrA[i]->foo(); delete a; delete aa; delete ab; return 0; }

以下是一个例子:

Invariant
  • 请记住,C ++是Contravariant而非derived,这意味着您无法为base对象分配A* a = new A; Ab* ab = a; // error 个对象:

    {{1}}

答案 1 :(得分:0)

有一个基本指针数组是有效的,你也可以使用dynamic_cast在运行时知道数组的返回类型,并使用派生类中的API。请参阅下面的示例。

struct Base { virtual void do_something() {} };

struct Derived1 : Base
{
  void first() const { std::cout << "first" << std::endl; }
  void do_something() override {}
};

struct Derived2 : Base
{
  void second() const { std::cout << "second" << std::endl; }
  void do_something() override {}
};

Base& get(int option)
{
  static std::vector<Base*> b {new Derived1{}, new Derived2{}};
  return !option ? *b[0] : *b[1];
}

int main()
{
  const int option {0};
  // const int option {1};

  if (Derived1* derived {dynamic_cast<Derived1*>(&get(option))})
  {
    derived->first();
  }
  else if (Derived2* derived {dynamic_cast<Derived2*>(&get(option))})
  {
    derived->second();
  }
}