我正在尝试创建一个读取多态动态数组的函数,并为每个类打印不同的东西。代码是这样的:
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)
我该怎么办?
答案 0 :(得分:3)
将动态广告代码应用于a
的地址,例如dynamic_cast<const B*>(&a)
。虽然引用是指针下的指针(有点),但你不能把它当作指针。
但是,我建议不要写这样的东西,它不会缩放。
PS - 正如评论者所说,你需要动态转换为const指针,而你的示例转换为非const。
答案 1 :(得分:2)
正如其他人所说,为什么不跳过演员?此外,如果你希望你的派生类表现出不同的行为,为什么不明确定义不同的行为?也就是说,使用dynamic_cast<>
说明你的意图 - 替代方案也是如此。
话虽如此,正如其他人所说,你的基类应该至少有一个virtual
函数,你的派生类应该是公开派生的。
class A {
public:
virtual void operator()() {
std::cout << "A\n";
}
virtual void print() {
std::cout << "A\n";
}
virtual ~A() = default;
};
class B : public A {
public:
void operator()() override {
std::cout << "B\n";
}
void print() override {
std::cout << "B\n";
}
};
class C : public A {
public:
void operator()() override {
std::cout << "C\n";
}
void print() override {
std::cout << "C\n";
}
};
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(); // ?
答案 2 :(得分:1)
我修改了你的代码,以便按你想要的方式工作。但我建议您不要这样做:使用new
/ delete
,new[]
/ 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
}