假设有一个A类,它有两个子类,Aa和Ab。我想创建一个可以存储指向Aa和Ab类对象的指针的数组。如果使用类A的类型声明数组,这是否有效?如果没有,我该怎么做到这一点?例如:
A *arr;
//space allocated
Ab *obj1;
arr[x] = obj1;
在相关的说明中,我想编写一个函数,当给定一个位置时,将返回存储在数组中该位置的对象。如果以上工作并且我有Aa或Ab的对象数组,则该函数可以返回Aa或Ab类型的对象。如果函数的返回类型指定为A,那么超类是否有效?如果没有,我已经查看了模板函数,但找不到关于返回类型是可变的直接答案,而不是参数。对于此示例,函数的参数始终为int
,但它可能返回Aa或Ab,具体取决于数组中该位置的内容。
答案 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();
}
}