有人可以帮我解决错误
conversion from `A' to non-scalar type `B' requested
我有A类并从中派生出B,但我对这些行有疑问:
A a(1);
A *pb = new B(a);
B b = *pb; //here I have an error
提前感谢任何帮助
class A {
protected:
int player;
public:
A(int initPlayer = 0);
A(const A&);
A& operator=(const A&);
virtual ~A(){};
virtual void foo();
void foo() const;
operator int();
};
class B: public A {
public:
B(int initPlayer): A(initPlayer){};
~B(){};
virtual void foo();
};
我有这个代码和(我不能改变它):
A a(1);
A *pb = new B(a);
B b = *pb;
我试图为B创建构造函数:
B::B(const A & a):
player(a.player){}
B& B::operator=(const A& a){
if(this == &a){
return *this;
}
player = a.player;
return *this;
}
但它给了我一个错误,真的需要专业人士的帮助
答案 0 :(得分:6)
您的问题是由静态类型检查引起的。如果你有这一行:
A *pb = new B(a);
pb
的静态类型为A *
,其动态类型为B *
。虽然动态类型是正确的,但编译器正在检查静态类型。
对于这个简单的代码,因为你知道pb
的动态类型总是B,你可以用静态强制转换来解决这个问题:
B b = *static_cast<B *>(pb);
但请注意,如果pb
的动态类型为A *
,则转换会导致未定义的行为。
答案 1 :(得分:1)
当您取消引用“A”指针时,即使它指向“B”,也会得到“A”。多态性在这里没有发挥作用!要将'B'属性保存到'A'对象,您应该按照其他一些答案中的说明正确地进行初始化。
答案 2 :(得分:0)
在这种情况下,动态演员表是最合适的。动态强制转换将调用运行时类型系统以找出“真实”类型的bp,如果无法转换为请求的类型,则返回0
。如您所知,实际类型也可以在这里使用static_cast
,但在这种情况下通常情况并非如此。
B* b = dynamic_cast<B*>(pb);
答案 3 :(得分:0)
*pb
会为您提供A&
而不是B&
。就像pb
是A*
而不是B*
一样,即使实际对象是B
。
B b = *pb
将尝试使用合成复制构造函数复制构造B
。因此,复制构造函数将查找B&
作为其参数。您没有构造函数从B
生成A
,因此出错。
正如@R Samuel Klatchko所说,你可以投它,或者,如果你已经给出,你可以让pb
实际上成为B*
。
答案 4 :(得分:0)
您正在尝试将类型A的对象分配给类型B的对象。除非您定义类型转换运算符,否则不允许这样做。 pb
是指向A对象的指针,通常它不是指向B的指针(在你的情况下它是,但它对编译器无关紧要,因为它被声明为指向A的指针)。为了使这样的分配成为可能,你首先需要将pb
向下投射到B的指针(正如 R Samuel Klatchko 指出的那样,在你的情况下static_cast
完全没问题;在您可能需要使用dynamic_cast
)的其他情况。