C ++:包含类实例的联合调用错误的虚函数 [英] C++: Union containing class instances calls wrong virtual function

查看:149
本文介绍了C ++:包含类实例的联合调用错误的虚函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个奇怪的现象,运行以下代码:

I came across a strange phenomena upon running the following code:

#include <iostream>    

class Piece {
public:
    class Queen;
    class Knight;
    union Any;
    virtual const char* name() const = 0;
};

class Piece::Queen : public Piece {
public:
    virtual const char* name() const {
        return "Queen";
    }
};

class Piece::Knight : public Piece {
public:
    virtual const char* name() const {
        return "Knight";
    }
};

union Piece::Any {
public:
    Any() {}
    Piece::Queen queen;
    Piece::Knight knight;
};

using namespace std;
int main(int argc, const char* argv[]) {
    Piece::Any any;
    any.queen = Piece::Queen();
    cout << any.queen.name() << endl;

    return 0;
}

程序在Apple LLVM 3.0编译器上已成功编译,但输出为骑士。
我期望输出是皇后。
从我的测试,我看到当Piece :: Any的默认构造函数运行,它调用的Piece :: Queen和Piece :: Knights的构造函数,一个接一个。如果我要声明Piece :: Any像这样:

The program compiled successfully on the Apple LLVM 3.0 compiler, but the output was "Knight". I was expecting for the output to be "Queen". From my testing I saw that when Piece::Any's default constructor runs, it calls both Piece::Queen and Piece::Knights' constructors, one after another. If I were to declare Piece::Any like this:

union Piece::Any {
public:
    Any() {}
    Piece::Knight knight;
    Piece::Queen queen;
};

(我基本上交换了骑士和女王的顺序),那么输出将是女王。

(I basically swapped the order of knight and queen) then the output would be Queen. Any help would be appreciated.

感谢

推荐答案

首先 - 你的构造函数似乎没有初始化它的成员。您应该选择一个,例如

First of all - your constructor seems to initialize none of its members. You should choose one, for example

Piece::Any::Any(): knight() {}

然后根据9.5.4


一般来说,必须使用显式析构函数调用和位置新运算符来更改联合的活动成员

In general, one must use explicit destructor calls and placement new operators to change the active member of a union

从骑士到女王是

any.knight.~Knight();
new(&any.queen) Queen;

如果它看起来很丑陋(就像对我一样),很清楚地表明,具有非平凡构造函数的联合对象不是一个好主意(如何boost :: variant?)。

If it looks ugly to you (as it does to me), it is clear indication, that keeping objects with non-trivial constructors in union is not a good idea (how about boost::variant?).

这篇关于C ++:包含类实例的联合调用错误的虚函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆