请求非标量类型

时间:2010-06-15 15:10:06

标签: c++ inheritance pointers

有人可以帮我解决错误

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;
}

但它给了我一个错误,真的需要专业人士的帮助

5 个答案:

答案 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&。就像pbA*而不是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)的其他情况。