首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

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

编译器不允许将std::string放置在union中的主要原因是std::string是一个动态分配的对象,它使用了堆内存来存储字符串数据。而union是一种特殊的数据结构,它的所有成员共享同一块内存空间。由于std::string的大小是可变的,它可能会动态分配不同大小的内存空间来存储字符串,这与union的内存布局不兼容。

另外,std::string类还包含了一些成员函数,如构造函数、析构函数、拷贝构造函数和赋值运算符等。这些成员函数在对象的生命周期中起到重要作用,但是在union中,由于所有成员共享同一块内存空间,无法保证这些成员函数的正确调用。

因此,为了避免内存布局的冲突和成员函数的调用问题,编译器不允许将std::string放置在union中。

对于需要在union中存储字符串的情况,可以考虑使用字符数组或者其他固定大小的字符串类型来代替std::string。这样可以避免动态内存分配和成员函数调用的问题。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

为什么StringJava是不可变的

String Java 是不可变的。 不可变类只是一个无法修改其实例的类。 创建实例时,将初始化实例的所有信息,并且无法修改信息。 不可变类有许多优点。...本文总结了为什么 String 设计为不可变的。 这篇文章从内存,同步和数据结构的角度说明了不变性概念。 1. 字符串池 字符串池(String intern pool)是方法区域中的特殊存储区域。...以下代码将在堆仅创建一个字符串对象。 String string1 = "abcd"; String string2 = "abcd"; 如下图所示: ?...例如, HashMap 或 HashSet 。 不可变保证哈希码总是相同的,这样它就可以缓存起来而不用担心变化。这意味着,每次使用时都不需要计算哈希码。 这更有效率。...String,它具有如下代码: private int hash;//this is used to cache hash code. 3.

1.3K20

javaString为什么要设计成final?

String为什么被定义为final面试中经常被问到。 首先,先得清楚 final 这个关键字。 final的出现就是为了为了不想改变,而不想改变的理由有两点:设计(安全)或者效率。...所有 *java程序的字符串,如“ABC”,是 *实现为这个类的实例。 * *字符串是常量,它们的值它们之后不能更改 *创建。支持可变字符串字符串缓冲区。...value用final修饰,编译器不允许我把value指向堆区另一个地址 final int[] value={1,2,3} int[] another={4,5,6}; value=another;...//编译器报错,final不可变 但如果我直接对数组元素动手 final int[] value={1,2,3}; value[2]=100; //这时候数组里已经是{1,2,100} 当String...为final类型时: package test; public class 为什么String要设计成不可变类 { public static void main(String[] args

93030
  • javaString为什么要设计成final?

    String不可变很简单,如下图,给一个已有字符串"abcd"第二次赋值成"abcedl",不是原内存地址上修改数据,而是重新指向一个新对象,新地址。 ? 2. String为什么不可变?...修饰,编译器不允许我把value指向堆区另一个地址。...示例1 package _12_01字符串;public class 为什么String要设计成不可变类你 { public static void main(String[] args) { String...如果String是可变的,就可能如下例,我们使用StringBuffer来模拟String是可变的 package _12_01字符串;public class 为什么String要设计成不可变类2 {...String one = "someString";String two = "someString"; ? 这样大量使用字符串的情况下,可以节省内存空间,提高效率。

    1.1K31

    javaString为什么要设计成final?Java面试常见问题

    因此,我们以后的开发,如果要经常修改字符串的内容,请尽量少用String!...Java,因为数组也是对象, 所以value存储的也只是一个引用,它指向一个真正的数组对象。执行了String s = “yiyige”; 这句代码之后,真正的内存布局应该是下图这样的: ?...正是基于这一层,我们才说String对象是不可变的对象。 所以String的不可变,其实是指value的引用地址不可变,而不是说常量池中value字符数组里的数据元素不可变。...为什么要用final修饰javaString类呢? 核心:因为它确保了字符串的安全性和可靠性。 2. javaString真的不可变吗?...只不过一般的描述,大家都会说String内容不可改变,毕竟很多时候是不允许利用反射这种特殊的功能去进行这样的操作的。

    40400

    C++:34---union:联合共用体,一种节省空间的类

    C++11标准,含有构造函数或析构函数的类类型也可以作为union的成员类型 union可以为其成员指定public、protected、private等标记。...因此,当我们使用union时,必须清楚的2知道当前存储union的值到底是什么类型。...四、匿名union 匿名union是一个未命名的union,并且右花括号和分号之间没有任何声明 一旦我们定义了一个匿名union编译器就自动地为该union创建一个未命名的对象 匿名union不能定义全局作用域中...含有特殊类类型成员时: 使用类管理union成员 对于union来说,想要构造或销毁类类型成员必须执行非常复杂的操作,因此我们通常把含有类类型成员的union内嵌另一个类。...=(const std::string& i) { //如果当前存储的就是string类型,那么直接赋值即可 if (tok == STR) sval = i; //如果不是,那么使用定位new,sval

    5.4K20

    多态实现-虚函数、函数指针以及变体

    实现 C++的虚函数的作用主要是实现运行时多态。基类声明一个虚(virtual)函数,然后派生类对其进行重写。...C++,因为允许函数重载,所以编译器需要对函数进行name mangling,而对于C,因为不允许重载,所以不存在name mangling操作。...但是,现在的很多编译器,大多采用的是Itanium C++指定的mangling标准。...我们可以将其理解为union的升级版,之所以称之为升级版,是因为union有如下缺点: 对象并不知道它们现在持有的值的类型 不能持有std::string等非平凡类型 不能被继承 既然称之为union的升级版...,如果访问器访问一个函数对象不支持的类型operator()重载时候,会导致编译器错误。

    92820

    C++17 在业务代码中最好用的十个特性

    WXG 编译器升级到 gcc7.5 已有一段时间,笔者所在项目组也已经将全部代码升级到 C++17。使用了 C++17 一年多之后,笔者总结了 C++17 在业务代码中最好用的十个特性。...::cout << key << ": " << value << std::endl;     }(); } 另外这条限制 c++20 已经被删除,所以 c++20 标准 gcc 和 clang...处理子串时,std::string::substr也需要进行拷贝和分配内存,而std::string_view::substr则不需要,处理大文件解析时,性能优势非常明显。...>代表一个多类型的容器,容器的值是制定类型的一种,是通用的 Sum Type,对应 Rust 的enum。是一种类型安全的union,所以也叫做tagged union。...与union相比有两点优势: 可以存储复杂类型,而 union 只能直接存储基础的 POD 类型,对于如std::vector和std::string就等复杂类型则需要用户手动管理内存。

    2.6K20

    c++17好用的新特性总结

    C++17之前,我们定义全局变量, 总需要将变量定义cpp文件,然后通过extern关键字来告诉编译器 这个变量已经在其他地方定义过了。...有兴趣的朋友可以看看下面两篇文章: 《c++ inline variable 内联变量 c++17》 《GCC,Clang C模式,较低优化等级下,链接器对内联函数报未定义错误,为什么?》...处理子串时,std::string::substr也需要进行拷贝和分配内存,而std::string_view::substr则不需要,处理大文件解析时,性能优势非常明显。...与union相比有两点优势: 可以存储复杂类型,而union只能直接存储基础的POD类型,对于如std::vector和std::string就等复杂类型则需要用户手动管理内存。...需要注意的是,c++17只提供了一个库级别的variant实现,没有对应的模式匹配(Pattern Matching)机制,而最接近的std::visit又缺少编译器的优化支持,所以c++17std

    3.2K10

    【Rust笔记】浅聊 Rust 程序内存布局

    具体的技术手段包括Rust编译器 重排了字段的存储顺序,以尽可能多地消减掉“边角料”(对齐填充)占用的字节位数。于是,源程序字段声明的词法次序经常不同于【运行时】它们在内存里的实际存储顺序。...按照字段源代码的词法声明次序,逐一遍历每个字段。...Cpp程序,需要借助【标准库】的Tagged Union数据结构才能模拟出同类的功能来。欲了解更多技术细节,推荐读我的另一篇文章。 禁忌:C内存布局的枚举类必须至少包含一个枚举值。...因为C ABI,结构体字段的存储次序就是它们源码的声明次序,所以Cpp标准库的Tagged Union数据结构总是,根据约定的字段次序, 将第一个字段解释为“选中项的索引号”, 将第二个字段解读为...即,#[repr(packed(x))]数据结构不允许嵌套包含#[repr(align(y))]子数据结构。 枚举类内存布局的微调 首先,枚举类不允许下调对齐位数。

    49820

    《C++Primer》第十九章

    编译器发现一条new表达式或者delete表达式后,将在程序查找可供调用的operator函数: 如果被分配(释放)的对象是类类型,则编译器首先在类及其基类的作用域中查找 否则在全局作用域中查找...(std::string, std::shared_ptr>, std::shared_ptr> f) : sought(s), lines(p), file(f) { } union: 一种节省空间的类 联合...举个例子,假设我们需要处理一些不同种类的数字数据和字符数据,则可以定义一个union来保存这些值: // Token类型的对象只有一个成员, 该成员的类型可能是下列类型的任意一个 union Token...局部类的成员必须完整定义类的内部,所以成员函数的复杂性不能太高,一般只有几行代码 局部类不允许声明静态数据成员 1.

    1.3K10

    【笔记】《深入理解C++11》(上)

    最终可以用is_pod::value直接判断是否POD 非受限联合 C++11后, 任何非引用类型都可以成为union的成员(包括函数), 因此称为非受限联合 不允许静态成员变量存在 union的一些默认函数将被删除..., 例如当存在非POD成员且这个成员有非平凡的构造函数时, 这个union的默认构造将被删除 匿名的union对外是开放的, 因此放在类的声明可以按照构造函数的不同而初始化为不同的类型, 此时类被称为枚举式的类..., 这个union被称为变长成员 内联名字空间 namespace嵌套namespace后, 调用内部内容可能很繁琐 如果用using打开一些内层的空间又可能与模板编程冲突, 因为模板不允许不同名称空间的名字模板特化...C++11的标准中提出SFINEA的动机是当年C++98并没有对这个规则进行标准化的描述, 因此各个编译器对于函数模板的匹配规则都是混乱的, 因此新标准提出SFINEA来使程序员能按照自己的想象来理解编译器并令其能精确匹配我们所需要的函数...::value << std::endl; // 输出 true } 这个特性C++20被concept以更好的语法取代 4 新手易学, 老兵易用 auto auto是静态类型推导, 必须被初始化

    1.9K20

    C++临时变量的常量性

    void print(string& str) { cout<<str<<endl; } //如此调用会报编译错误 print("hello world"); Linux环境使用g++编译,会出现:...invalid initialization of non-const reference of type ‘std::string&’ from a temporary of type 'std::...出错的原因是编译器根据字符串"hello world"构造一个string类型的临时对象,这个临时变量具有const属性,当这个临时变量传递给非const的string&引用类型时,无法隐式完成const...2.临时变量常量性的原因 为什么临时对象作为引用参数传递时,形参必须是常量引用呢?很多人对此的解释是临时变量是常量,不允许赋值改动,所以作为非常量引用传递时,编译器就会报错。...注意,这里与《C++编程思想》第八章的“临时量”小节认为“编译器使所有的临时量自动设为const”的说法有些不同。 那编译器为何作出如此限制呢?

    2K31

    老梁聊C++,为什么不能修改set里的值?如果非要修改怎么办?

    说白了,也就是编译器进行了限制,不允许我们对set迭代器的内容进行修改。 Effective C++当中也明确说了,不要对set集合的元素进行修改。...也很简单,大概率因为你用的是vc编译器,比如臭名昭著的VC6.0或者是visual studio IDE(不是VSCode)。微软的编译器没有严格遵循C++的标准,很多地方有些瑕疵和随意。...说人话就是std::set其实不允许将元素定义成const,既然元素不是const类型,那么就说明理论上是可以修改的。...我们开始之前,首先思考一个问题,既然set底层源码当中的元素并不是定义成const,那么当我们去用迭代器去修改的时候为什么会报错呢? 要回答这个问题,我们只需要查看一下set迭代器的源码定义即可。...有些同学可能会觉得疑惑,我们加上const的目的不就是为了对变量做限制,从而可以在编译的时候通过编译器来替我们检查一些非法的操作吗?既然如此,又为什么需要去掉呢?

    1.1K20

    C到C++II

    STU stu = { 18,"小明" }; stu.introduce(); //调用结构体里面的函数 return 0; } C++联合 声明或定义联合变量,可以省略union...支持匿名联合 //匿名联合示例 匿名联合不能作为全局,只能放在函数里面 #include int main(){ union{ char c;...枚举类型可以隐式转换成整型 //color = 1; //不允许 会报错不能将 "int" 类型的值分配到 "Color" 类型的实体 color = RED; //类型检查更为严格...提高效率,避免函数调用开销 使用inline关键字期望该函数被优化为内联,是否内联由编译器决定,看你系统的心情决定是否优化。 内联会使可执行文件内存变大,只有频繁调用的简单函数适合内联。...return 0; } 注意:被const修饰的变量被引用时必须被const修饰 const int a = 10; const int& A = a; 引用做参数 节省空间+提高效率 函数

    1.2K30

    临时变量作为非const的引用进行参数传递引发的编译错误

    :string&’ from a temporary of type ‘std::string’的错误。...也就是参数传递的过程,出现错误。...出错的代码如下: void print(string& str) { cout<<str<<endl; } //如此调用会报上面描述的错误 print("hello world"); 出错的原因是编译器根据字符串...---- 2.所有的临时对象都是const对象吗 为什么临时对象作为引用参数传递时,必须是常量引用呢?很多人对此的解释是临时对象是常量,不允许赋值改动,所以作为非常量引用传递时,编译器就会报错。...IntClass(6)表示生成一个无名的临时对象,传递给非const引用,print函数通过引用修改了这个临时对象。这说明了并非所有的临时对象都是const对象。

    2.5K31

    c++11新特性,所有知识点都在这了!

    auto:让编译器编译器就推导出变量的类型,可以通过=右边的类型推导出变量的类型。...,而通过default,程序员只需函数声明后加上“=default;”,就可将该函数声明为 defaulted 函数,编译器将为显式声明的 defaulted 函数自动生成函数体,如下: struct...delete c++,如果开发人员没有定义特殊成员函数,那么编译器需要特殊成员函数时候会隐式自动生成一个默认的特殊成员函数,例如拷贝构造函数或者拷贝赋值操作符,如下代码: struct A {...非受限联合体 c++11之前union数据成员的类型不允许有非POD类型,而这个限制c++11被取消,允许数据成员类型有非POD类型,看代码: struct A { int a; int...c++11是不是方便了许多,而不需要定义一个对象,计算对象的成员大小。

    19.2K24
    领券