频道栏目
首页 > 程序开发 > 软件开发 > C++ > 正文
union一种节省空间的类类型成员
2017-10-11 09:22:05      个评论    来源:u010599761的专栏  
收藏   我要投稿

含有类类型成员的union:

c++早期版本规定,在union中不能含有定义了构造函数或拷贝控制成员的类类型成员。

当union包含的是内置类型的成员时,编译器将按照成员的次序依次合成默认构造函数或拷贝控制成员。但是如果union含有类类型的成员,并且该类型自定义了默认构造函数或拷贝控制成员,则编译器将为union合成对应的版本并将其声明为删除的

所以需要使用类来管理union成员

class Token

{

public:

//因为union 含有一个string成员,所以Token必须定义拷贝控制成员

Token():tok(INT), ival(0){}

Token(const Token &t):tok(t.tok)

{ copyUnion(t);qDebug() << "....value constructer";}

Token(Token&&t) noexcept:tok(t.tok)

{ copyUnion(t);qDebug() << "....move constrrcter";}

Token &operator =(Token &&rhs) noexcept

{

if ( this != &rhs )

{

if ( STR == tok && STR != rhs.tok )

{

sval.~string();

}

if ( STR == tok && STR == rhs.tok)

{

sval = rhs.sval;

}

else

{

copyUnion(rhs);

}

}

qDebug() << ".....move operator=";

return *this;

}

Token &operator=(const Token &rhs)

{

if ( this != &rhs )

{

if ( STR == tok && STR != rhs.tok )

{

sval.~string();

}

if ( STR == tok && STR == rhs.tok)

{

sval = rhs.sval;

}

else

{

copyUnion(rhs);

}

}

qDebug() << ".....value opeartor=";

return *this;

}
//如果union含有一个string成员,则我们必须销毁它,(调用析构函数会销毁对象,但是不会释放内存,如果需要的话,可以重新使用该空间)

//因为析构函数不清楚union存储的值是什么类型,所以它无法确定应该销毁那个成员

~Token() { if (STR == tok) sval.~string(); }

//下面的赋值运算符负责设置union的不同成员

Token &operator =(const std::string &s)

{

if ( STR == tok )

{

sval = s;

}

else

{

new (&sval) string(s);

}

tok = STR;

return *this;

}

Token &operator =(char c)

{

if ( STR == tok )

{

sval.~string();

}

cval = c;

tok = CHAR;

return *this;

}

Token &operator =(int i)

{

if (STR == tok )

{

sval.~string();

}

ival = i;

tok = INT;

return *this;

}

Token &operator =(double d)

{

if ( STR == tok )

{

sval.~string();

}

dval = d;

tok = DBL;

return *this;

}

private:

enum { INT, CHAR, DBL, STR } tok;//判别式

union {//匿名 union

char cval;

int ival;

double dval;

std::string sval;

};//每个Token对象含有一个改未命名union类型的未命名成员

//检查判别式,然后酌情拷贝union成员

void copyUnion(const Token&rhs)

{

switch (rhs.tok) {

case INT:

ival = rhs.ival;

break;

case DBL:

dval = rhs.dval;

break;

case CHAR:

cval = rhs.cval;

break;

case STR:

new (&sval) string(rhs.sval);

break;

default:

break;

}

}

};

union类(联合)硬性知识

union不能含有引用类型的成员,在c++新标准中, 含有构造函数或析构函数的类类型也可以作为union的成员类型。union可以为其成员指定public, protected和private保护标记,默认是共有的。union可以定义包含构造函数和析构函数在内的成员函数。但是不能继承也不能被继承,所以union不能含有虚函数。

匿名的union:

不能标记protected, private,也不能定义成员函数。

点击复制链接 与好友分享!回本站首页
上一篇:如何使用VS Code上编译运行C/C++程序
下一篇:最后一页
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站