c ++ 11联合包含具有虚函数的数据成员 [英] c++11 union contains data member with virtual function

查看:111
本文介绍了c ++ 11联合包含具有虚函数的数据成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#include <iostream>
class derive1{
  public:
    derive1() = default;
    ~derive1() = default;
    virtual void func() { std::cout << "derive 1" << std::endl; }
};

class derive2 {
  public:
    derive2() = default;
    ~derive2() = default;
    virtual void func() { std::cout << "derice 2" << std::endl; }
};

union classUnion {
  classUnion() {};
  ~classUnion() {};
  derive1 obj1;
  derive2 obj2;
};

int main() {
  classUnion u1;
  u1.obj1.func();  // <-- OK print 'derive 1'
  derive1 &dev1 = u1.obj1;
  dev1.func(); // <-- OK print 'derive 1'
  derive1 *ptr = &(u1.obj1);
  ptr->func(); // <-- core dump/seg fault
  return 0;
}

我认为C ++ 11允许使用非平凡的构造函数(带有虚函数) 。
我看不到这里有什么问题。
我使用
g ++ -std = c + 11 test.cpp进行编译(gcc 4.8和gcc 5.0)。

I thought C++11 allow non-trivial constructor (with virtual function). I can't see what's the problem here. I use "g++ -std=c+11 test.cpp" to compile it (gcc 4.8 and gcc 5.0).

推荐答案

问题是您永远不会在联合体内初始化对象。至少,最简单的方法就是进行以下一些小的调整:

The problem is that you never initialize the object inside the union. At least, the easiest way to make it work is the following little tweak:

union classUnion {
  classUnion() {};
  ~classUnion() {};
  derive1 obj1={}; // unions can have one inline initializer
  derive2 obj2;
};

但是,如果您改为这样做:

However, if you instead do this:

int main() {
  classUnion u1;
  u1.obj1 = derive1{};
  ...
}

它仍然会崩溃。原因是因为您要分配给未初始化的对象,特别是您具有用户定义的析构函数(即虚拟析构函数)。

It still will crash. The reason why is because you are assigning into an uninitialized object, and in particular you have a user defined destructor (i.e. a virtual one).

请考虑以下内容:
http://zh.cppreference.com/w/cpp/language/union 。)


如果是成员联合的一部分是具有用户定义的构造函数和
析构函数的类,通常需要切换活动成员,显式析构函数和
放置新值:

If members of a union are classes with user-defined constructors and destructors, to switch the active member, explicit destructor and placement new are generally needed:

因此,要实际使用带有虚函数的类(通常需要虚拟析构函数),您将需要使用放置新的和手动销毁调用,例如:

So to realistically use classes with virtual functions (which typically need virtual destructors), you're going to need to use placement new and manual destruction calls, like so:

int main() {
  classUnion u1;
  new (&u1.obj1) derive1{};
  ... // use obj1
  u1.obj1.~derive1();
  new (&u1.obj2) derive2{};
  ... // use obj2
  u1.obj2.~derive2();
}

这篇关于c ++ 11联合包含具有虚函数的数据成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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