相关疑难解决方法(0)

为什么编译器不允许std :: string在union中?

我想在Union里面使用字符串.如果我写如下

union U
{
   int i;
   float f;
   string s;
};
Run Code Online (Sandbox Code Playgroud)

编译器给出错误,说U :: S有复制构造函数.

我读了一些其他帖子,了解解决这个问题的其他方法.但我想知道为什么编译器首先不允许这样做?

编辑:@KennyTM:在任何联合中,如果成员被初始化,其他人将具有垃圾值,如果没有初始化,则所有将具有垃圾值.我认为,标记联合只是为从Union访问有效值提供了一些安慰.您的问题:您或编译器如何在没有额外信息的情况下为联合编写复制构造函数?sizeof(string)给出4个字节.基于此,编译器可以比较其他成员大小并分配最大分配(在我们的示例中为4字节).内部字符串长度无关紧要,因为它将存储在单独的位置.让字符串为任意长度.Union必须知道的是使用字符串参数调用字符串类复制构造函数.无论哪种方式编译器发现在正常情况下都必须调用复制构造函数,即使字符串在Union中,也要遵循类似的方法.所以我认为编译器可以这样做,分配4个字节.然后,如果为s分配了任何字符串,则字符串类将使用其自己的分配器来处理该字符串的分配和复制.所以也没有内存损坏的可能性.

编译器中Union开发时不存在字符串吗?所以我的答案还不清楚.我是这个网站的新工作人员,如果有什么不对,请原谅.

c++

45
推荐指数
4
解决办法
2万
查看次数

在已销毁对象的存储中使用当前对象是否安全?

在此代码示例中,使用放置 new 在另一个对象的存储中创建一个对象,并且永远不会访问释放的内存。

以下是事件的顺序:

  1. 新的 Object1 在分配的内存中创建。Object2 是一个联合体,因此不会被触及。
  2. 使用placement new 在Object1 内部创建Object2
  3. 对象 1 被破坏。对象 2 未受影响。
  4. 打印object2的内容
  5. 调用 Object2 析构函数
  6. Object1 的内存已删除

这安全吗?

#include <stdio.h>
#include <new>

struct Object2
{
    char a{1};
    char b{2};
    char c{3};
};

struct Object1
{
    //
    // disconnect Object2 lifetime from Object1
    //
    
    union
    {
        Object2 o;
    };

    char d{3};

    Object1()
    {
    }
};

int main(int argc, char* argv[])
{
    //
    // Create object1, internal object2 is not yet constructed
    //
    
    Object1* object1 = …
Run Code Online (Sandbox Code Playgroud)

c++ constructor lifetime language-lawyer

6
推荐指数
0
解决办法
102
查看次数

工会成员的析构函数似乎是自动调用的

我正在尝试实施标记联合。

我的理解是,在 C++ 联合中,非静态成员的非平凡(即非空)析构函数永远不会被调用,因此我们必须自己调用它们。这就是我所做的:

#include <iostream>

class C {
public:
  C() {
    std::cout << "C Ctor" << std::endl;
  }
  ~C() {
    std::cout << "C Dtor" << std::endl;
  }
};

class B {
public:
  B() {
    std::cout << "B Ctor" << std::endl;
  }
  ~B() {
    std::cout << "B Dtor" << std::endl;
  }
};

struct S {
  int type;

  union U {
    C c;
    B b;

    U() {

    }

    ~U() {}
  } u;

  S(int type) : type(type) {
    if (type …
Run Code Online (Sandbox Code Playgroud)

c++ union destructor

3
推荐指数
1
解决办法
110
查看次数

为什么要将结构包装在匿名联合中?(STL msvc 实现)

STL<memory>标头(MSVC 实现)包含一个名为:

template <class _Ty> class _Ref_count_obj2 : public _Ref_count_base
Run Code Online (Sandbox Code Playgroud)

这个类有一个成员:

union {
    _Wrap<_Ty> _Storage;
};
Run Code Online (Sandbox Code Playgroud)

其中 _Wrap 定义为:

template <class _Ty> 
struct _Wrap {
    _Ty _Value; // workaround for "T^ is not allowed in a union"
};
Run Code Online (Sandbox Code Playgroud)

根据我的理解,这段代码旨在通过new操作符在构造之后保存一个 _Ty 类型的对象。但是我不明白为什么这样做;似乎使用 astruct而不是structinside aunion也能正常工作。

任何人都可以解释这背后的原因吗?另外,任何人都可以解释 _Wrap 定义中的注释吗?

c++ templates struct c++-standard-library unions

3
推荐指数
1
解决办法
110
查看次数

引用已删除的析构函数

我有以下代码:

struct Foo
{
    int type;
    union
    {
        int intValue;
        double doubleValue;
        std::wstring stringValue;
    } value;
};
Run Code Online (Sandbox Code Playgroud)

然后在cpp文件中我有:

std::vector<Foo> row;
some_class_object->func( row );
Run Code Online (Sandbox Code Playgroud)

我得到了:

error C2280: 'void *Foo::__delDtor(unsigned int)': attempting to reference a deleted function 
Run Code Online (Sandbox Code Playgroud)

这里有什么问题?

编辑:

所以我添加了这个析构函数:

~Foo()
{
    if( type ==3 )
        value.stringValue.~std::wstring();
}
Run Code Online (Sandbox Code Playgroud)

我得到了一个错误:

error C2061: syntax error: identifier 'wstring'.
Run Code Online (Sandbox Code Playgroud)

在这种情况下,显然 std::string 与 std::wstring 很重要......

不知道。

编辑2:

我现在得到:

 error C2280: 'Foo::<unnamed-type-value>::~<unnamed-type-value>(void)': attempting to reference a deleted function
Run Code Online (Sandbox Code Playgroud)

c++ c++11

0
推荐指数
1
解决办法
80
查看次数