Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;11 union包含具有虚拟函数的数据成员 #包括 派生类1{ 公众: derive1()=默认值; ~derive1()=默认值; virtual void func(){std::cout_C++_C++11_Unions - Fatal编程技术网

C++ c++;11 union包含具有虚拟函数的数据成员 #包括 派生类1{ 公众: derive1()=默认值; ~derive1()=默认值; virtual void func(){std::cout

C++ c++;11 union包含具有虚拟函数的数据成员 #包括 派生类1{ 公众: derive1()=默认值; ~derive1()=默认值; virtual void func(){std::cout,c++,c++11,unions,C++,C++11,Unions,问题在于您从未初始化联合内部的对象。至少,使其工作的最简单方法是以下小调整: #include <iostream> class derive1{ public: derive1() = default; ~derive1() = default; virtual void func() { std::cout << "derive 1" << std::endl; } }; class derive2 { public:

问题在于您从未初始化联合内部的对象。至少,使其工作的最简单方法是以下小调整:

#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;
}
但是,如果您改为这样做:

union classUnion {
  classUnion() {};
  ~classUnion() {};
  derive1 obj1={}; // unions can have one inline initializer
  derive2 obj2;
};
它仍然会崩溃。原因是您正在分配到一个未初始化的对象,特别是您有一个用户定义的析构函数(即虚拟析构函数)

考虑以下几点: ()

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

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

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

在您的示例中,对
func()
的调用都不正常,它们都是未定义的行为。
union
不会默认初始化其任何成员;如果要这样做,它会初始化哪个成员

为了演示这一点,将非静态数据成员添加到
derive1
并在
func()
中打印它,您将看到垃圾值,或者您的程序将更早崩溃

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

classUnion() : obj1() {};


至于为什么在您的示例中对
func()
的前两个调用似乎有效,我猜gcc将这些函数调用内联,但在处理
derived1*
时它没有这样做,这导致最后一个调用失败。

您从未构造过任何东西。C++11允许非平凡的构造函数,但必须手动调用它们(编译器本身无法知道您要“激活”的联合成员”)
=
不起作用,因为您正在对一个不存在的对象调用成员函数。@t.C.有趣的是,我在您发表评论的那一刻修改了我的猜测。是的,我想就是这样。我想我可以修改答案以减少它的推测性。
classUnion() : obj1() {};
 derive1 obj1 = {};