21 c++ string constructor
我有一个看起来像这样的联盟:
union {
int intValue;
double doubleValue;
std::string stringValue;
void *pointerValue;
} values;
Run Code Online (Sandbox Code Playgroud)
当我编译它时,我收到此错误消息(是的,我做了#include <string>
):
./Value.hh:19:19: error: union member 'stringValue' has a non-trivial copy constructor
std::string stringValue;
^
/Developer/SDKs/MacOSX10.7.sdk//usr/include/c++/4.2.1/bits/basic_string.h:434:7: note: because
type 'std::basic_string<char>' has a user-declared copy constructor
basic_string(const basic_string& __str);
^
Run Code Online (Sandbox Code Playgroud)
我使用这个命令编译它:
$ clang++ *.cc -isysroot /Developer/SDKs/MacOSX10.7.sdk/ -shared
Run Code Online (Sandbox Code Playgroud)
我怎样才能std::string
在工会中使用?
Nic*_*las 26
你不能.
联合组合了两个功能:存储可能具有选定数量类型的对象的能力,以及在这些类型之间有效(和实现定义)转换的能力.您可以放入一个整数并将其表示视为double.等等.
因为联合必须支持这两种功能(并且由于其他一些原因,例如能够构造一个),因此联合会阻止您执行某些操作.也就是说,您不能在其中放置"实时"对象.任何"生活"足够需要非默认复制构造函数的对象(在许多其他限制中)都不能成为联合的成员.
毕竟,union对象实际上并不具有它实际存储的数据类型的概念.它不存储一种类型的数据; 它同时存储所有这些.你可以钓到正确的类型.那怎么能合理地将一个联盟价值复制到另一个呢?
union的成员必须是POD(普通旧数据)类型.虽然C++ 11确实放松了这些规则,但对象仍然必须具有默认(或其他微不足道的)复制构造函数.并且std::string
复制构造函数非常重要.
你可能想要的是一个boost::variant
.这是一个可以存储许多可能类型的对象,就像联合一样.然而,与联盟不同,它是类型安全的.因此,它知道联盟中究竟是什么; 因此,它可以复制自身,并且行为类似于常规C++对象.
你不能把std::string
一个联盟.它被C++语言禁止,因为它不安全.考虑到大多数std::string
实现都有一个指向某个动态内存的指针,该内存保存字符串的值.还要考虑无法知道哪个工会成员当前处于活动状态.
实现不能调用析构函数std::string
,因为它不知道该std::string
对象是当前活动的成员,但如果它不调用析构函数,那么内存将被泄露.
归档时间: |
|
查看次数: |
15342 次 |
最近记录: |