在 c++ 中动态强制转换 ** 数组

Dynamic casting a ** array in c++

本文关键字:转换 数组 c++ 动态      更新时间:2023-10-16

>我正在尝试创建一个函数来读取多态动态数组并为每个类打印不同的东西。代码是这样的:

class A {};
class B: public A {};
class C: public A {};
void function (const A &a) {
if(B *b = dynamic_cast<B*>(a)){
cout << "B" << endl;
}
if(C *c = dynamic_cast<C*>(a)){
cout << "C" << endl;
}
}
int main () {
A **array = new A* [2];
array [0] = new B;
array [1] = new C;
function (array [0]); // To print B
function (array [1]); // To print C
}

但它给了我一个错误,说:

cannot dynamic_cast ‘a’ (of type ‘const class A’) to type ‘class B*’ (source is not a pointer)

我能做什么?

a的地址应用动态强制转换,例如dynamic_cast<const B*>(&a).虽然引用确实是引擎盖下的指针(有点(,但您不能仅将其视为指针。

但是,我建议不要写这样的东西,因为它无法扩展。

PS - 正如评论者所建议的那样,您需要动态转换为常量指针,而您的示例则转换为非常量指针。

正如其他人所说,为什么不跳过演员阵容呢?此外,如果您希望派生类表现出不同的行为,为什么不显式定义不同的行为呢?也就是说,使用dynamic_cast<>可以说明您的意图 - 替代方案也是如此。

话虽如此,正如其他人也说过的那样,基类应该至少有一个virtual函数,并且派生类应该是公开派生的。

class A {
public:
virtual void operator()() {
std::cout << "An";
}
virtual void print() {
std::cout << "An";
}
virtual ~A() = default;
};
class B : public A {
public:
void operator()() override {
std::cout << "Bn";
}
void print() override  {
std::cout << "Bn";
}
};
class C : public A {
public:
void operator()() override {
std::cout << "Cn";
}
void print() override {
std::cout << "Cn";
}
};
int main()
{
std::vector<A*> v;
auto pa = new A{};
auto pb = new B{};
auto pc = new C{};
v.push_back(pa);
v.push_back(pb);
v.push_back(pc);
for(auto& elem : v)
elem->print();
delete pa;
delete pb;
delete pc;
return 0;
}

我认为这是回答你问题的一部分。我相信你的问题的另一部分可以回答:

std::vector<A> vv;
A a;
B b;
C c;
a(); // A
b(); // B
c(); // C
vv.push_back(a);
vv.push_back(b);
vv.push_back(c);
for(auto& elem : vv)
elem(); // ?

我修复了您的代码,以便它以您想要的方式工作。 但我建议你不要这样做:使用new/deletenew[]/delete[]和原始指针不是最佳实践。 使用dynamic_cast是一种非常糟糕的代码气味。

#include <iostream>
using std::cout;
using std::endl;
namespace
{
class A
{
public:
virtual ~A() = default;
};
class B: public A
{
};
class C: public A
{
};
void function (A const& a)
{
if (B const* b = dynamic_cast<B const*>(&a))
{
cout << "B" << endl;
}
if (C const* c = dynamic_cast<C const*>(&a))
{
cout << "C" << endl;
}
}
} // anonymous namespace
int main ()
{
A* array[2] =
{
new B,
new C
};
function(*array[0]); // To print B
function(*array[1]); // To print C
}