C++ Primer(第5版) 练习 19.23
练习 19.23 为你的Token类添加移动构造函数和移动赋值运算符。
环境:Linux Ubuntu(云服务器)
工具:vim
代码块
class Token{
public:
Token(): tok(INT), ival(0) {}
Token(const Token &t): tok(t.tok) { copyUnion(t); }
Token &operator=(Token &&t) noexcept;
Token &operator=(const Token&);
~Token() { if(tok == STR) sval.~string(); }
Token &operator=(const std::string&);
Token &operator=(char);
Token &operator=(int);
Token &operator=(double);
private:
enum {INT, CHAR, DBL, STR} tok;
union{
char cval;
int ival;
double dval;
std::string sval;
};
void copyUnion(const Token&);
void moveUnion(Token &&t);
};
Token &Token::operator=(int i){
if(tok == STR){
sval.~string();
}
ival = i;
tok = INT;
return *this;
}
Token &Token::operator=(char c){
if(tok == STR){
sval.~string();
}
cval = c;
tok = CHAR;
return *this;
}
Token &Token::operator=(double d){
if(tok == STR){
sval.~string();
}
dval = d;
tok = DBL;
return *this;
}
Token &Token::operator=(const std::string &s){
if(tok == STR){
sval = s;
}
else{
new(&sval) string(s);
}
tok = STR;
return *this;
}
void Token::copyUnion(const Token &t){
switch(t.tok){
case Token::INT: ival = t.ival; break;
case Token::CHAR: cval = t.cval; break;
case Token::DBL: dval = t.dval; break;
case Token::STR: new(&sval) string(t.sval); break;
}
}
Token &Token::operator=(const Token &t){
if(tok == STR && t.tok!= STR) sval.~string();
if(tok == STR && t.tok == STR){
sval = t.sval;
}
else{
copyUnion(t);
}
tok = t.tok;
return *this;
}
Token &Token::operator=(Token &&t) noexcept{
if(this != &t) {
if(tok == STR) sval.~string();
moveUnion(std::move(t));
tok = t.tok;
}
return *this;
}
void Token::moveUnion(Token &&t){
switch(t.tok) {
case INT: ival = t.ival; break;
case CHAR: cval = t.cval; break;
case DBL: dval = t.dval; break;
case STR: new(&sval) std::string(std::move(t.sval)); break;
}
t.tok = INT;
}
标签:string,sval,运算符,tok,Token,STR,operator,移动,构造函数
From: https://blog.csdn.net/navicheung/article/details/141504993