这基本上是一个标记联合:
#include <string>
using std::string;
struct test{
test():tag(INT),i(0){};
test(const test&)=delete;
test& operator=(const test&)=delete;
enum {STRING,INT} tag;
union {
string s;
int i;
};
test& operator=(string s){
this->s=s;
tag=STRING;
return *this;
}
test& operator=(int i){
this->i=i;
tag=INT;
return *this;
}
~test(){
if (tag==STRING)
s.~string();
}
};
int main(){
test instance;
instance="string";
return 0;
}
它可以编译,但每次都会因分段错误而崩溃。我只是出于好奇,它是一个非常完整的联合类,提供了自定义析构函数,没有移动也没有复制,那么为什么会崩溃呢?我必须使用string*
在工会?如果是这样,为什么?
仔细阅读有关五法则 https://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29在 C++11 中
这是错误的代码:
/// wrong code
test& operator=(string s){
this->s=s;
tag=STRING;
return *this;
}
因为你错误地认为this->s
在分配之前有效。你应该使用安置新 http://en.cppreference.com/w/cpp/memory/new/operator_new which 结构体它(在一个未初始化的内存区域起始于&this->s
):
test& operator=(string ss){
if (tag==STRING) { s=ss; return *this; }
new((void*)&s) std::string(ss);
tag=STRING;
return *this;
}
顺便说一句,我想你也应该明确define
test(const test&s);
test(const std::string&);
test& operator=(const test&);
test(test&&s);
test& operator=(test&&);
顺便说一句,你显然缺少构造函数:
test(const std::string&str) {
tag = STRING;
new ((void*)(&s)) std::string(str);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)