C++11通过拷贝构造器拷贝const字段(待解决)

问题梗概如标题所述。

在今天实现Token类的时候,遇到的问题。

我希望将Token类设定为immutable属性的,这样实现的方式是将这个类内的所有字段均设置为const型,同时每个字段均为public可访问型。

类内主要有两个字段:mark(枚举类型,用于标记当前Token对象所代表的具体类型,比如INT,CHAR等);匿名union字段,用于存储mark标记下对应的具体值。

当我把两个字段均设置为const型时,拷贝构造器将会面临一些实现上的困难。

简言之,如果这样来写拷贝构造器:

 1 class Token {
 2 public:
 3     const Mark mark;
 4     const union {
 5         int ival;
 6         char cval;
 7     }
 8 
 9     Token(const Token &tk) : mark(tk.mark) {
10         if (tk.mark == INT) {
11             ival = tk.ival;
12         } else if (tk.mark == CHAR) {
13             cval = tk.cval;
14         }
15     } // 存在问题
16 
17     Token &operator=(const Token &tk) {
18         // 问题类似
19     }
20 ...
21 };

将会因为const字段无法被赋值而报错。

问题的关键就在于,只有确定了mark的具体值时,才能确定应该拷贝匿名union字段的哪个字段值。

暂时未解决该问题,望读者分享自己的想法。

 

此外,在编译过程中,遇到了clang的如下警告:

warning: all paths through this function will call itself
[-Winfinite-recursion]

1 warning generated.

报错代码:

1 std::ostream &operator<<(std::ostream &os, const Token &tok) {
2     os << "Tk:" << tok.getMark() << " " << tok.getLexeme();
3     return os;
4 }

其中getMark方法定义如下:

1 Mark Token::getMark() const {
2     return mark;
3 }

即直接将mark字段值返回(该字段是一个枚举类类型值,枚举类为Mark)。

此时执行Warning代码,会发现程序循环输出"Tk:"(Tk:Tk:Tk:Tk:....)。

此时,需要将枚举类型值强制转换为int型,实现正常输出。修改后的代码:

1 std::ostream &operator<<(std::ostream &os, const Token &tok) {
2     os << "Tk:" << (int)tok.getMark() << " " << tok.getLexeme();
3     return os;
4 }

至于为何出现这样的问题,初步猜测是和枚举类的内部实现有关。

针对出现这个问题的具体原因,欢迎分享想法。

 

2019.09.19

Modnar

posted @ 2019-09-19 22:08  Modnar  阅读(834)  评论(0编辑  收藏  举报