问题梗概如标题所述。

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

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

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

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

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

 class Token {
public:
const Mark mark;
const union {
int ival;
char cval;
} Token(const Token &tk) : mark(tk.mark) {
if (tk.mark == INT) {
ival = tk.ival;
} else if (tk.mark == CHAR) {
cval = tk.cval;
}
} // 存在问题 Token &operator=(const Token &tk) {
// 问题类似
}
...
};

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

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

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

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

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

1 warning generated.

报错代码:

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

其中getMark方法定义如下:

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

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

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

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

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

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

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

2019.09.19

Modnar

C++11通过拷贝构造器拷贝const字段(待解决)的更多相关文章

  1. C/C++(C++拷贝构造器,赋值运算符重载)

    拷贝构造器 由己存在的对象,创建新对象.也就是说新对象,不由构造器来构造,而是由拷贝构造器来完成.拷贝构造器的格式是固定的. class 类名 { 类名(const 类名 & another) ...

  2. [c++基础]3/5原则--拷贝构造函数+拷贝赋值操作符

    /* * main.cpp * * Created on: Apr 7, 2016 * Author: lizhen */ #include <iostream> #include &qu ...

  3. Win7 64位 + LoadRunner 11录制时弹不出IE的解决办法 Win7 64位 + LoadRunner 11录制时弹不出IE的解决办法

    Win7 64位 + LoadRunner 11录制时弹不出IE的解决办法 Win7 64位 + LoadRunner 11录制时弹不出IE的解决办法 1. 卸载IE9( 装了Win7 64位后,默认 ...

  4. 拷贝构造函数和const成员函数

    实验原因 说明如何使用const描述保护类数据不会意外修改. 编译环境 vc6sp6 + win7x64 工程下载 copyConstruction_constMemberFunction.zip   ...

  5. C++11如何减少内存拷贝次数

    C++11中出现了很多迷人的特性.例如智能指针实现高效的内存管理,std::bind和std::function函数封装器,以及lambda实现的函数对象语法糖,都是使我着迷的地方. 而C++11最大 ...

  6. C++ 拷贝构造函数之const关键字

    class Complex { public: //拷贝构造函数1 Complex(const Complex &c); //拷贝构造函数2 Complex(Complex &c); ...

  7. 拷贝构造函数 & 拷贝赋值运算符

    一.拷贝构造函数 1. 形式 class A { public: // ... A(const A &); // 拷贝构造函数 }; 2. 合成拷贝构造函数 编译器总会为我们合成一个拷贝构造函 ...

  8. Installshield更新时,新加dll未拷贝至安装目录问题完美解决【原创】

    最近在发现在开发过程中新增的目录或文件(特别是dll\ocx\exe等二进制文件),在升级安装时拷贝失败. 经过一周的研究,完美解决办法: 对于新增的文件或目录,放到一个新的component中,并且 ...

  9. Python 关于拷贝(copy)汇总(列表拷贝 // 字典拷贝 // 自定义对象拷贝)

    1.列表拷贝 引用是指保存的值为对象的地址.在 Python 语言中,一个变量保存的值除了基本类型保存的是值外,其它都是引用,因此对于它们的使用就需要小心一些.下面举个例子: 问题描述:已知一个列表, ...

随机推荐

  1. 「JSOI2015」isomorphism

    「JSOI2015」isomorphism 传送门 我们还是考虑树哈希来判同构. 但是我们需要使用一些特殊的手段来特殊对待假节点. 由于是无向树,我们首先求出重心,然后以重心为根跑树哈希. 此处我们不 ...

  2. 2019CSP-S T1格雷码

    题目大意: 格雷码(Gray Code)是一种特殊的 nn 位二进制串排列法,它要求相邻的两个二进制串间恰好有一位不同,特别地,第一个串与最后一个串也算作相邻. nn 位格雷码不止一种,下面给出其中一 ...

  3. 将.NET Core Web Api发布到Linux(CentOS 7 64)

    将.NET Core(2.1) Web Api发布到Linux(CentOS 7 64) 近来在学习linux相关的一些东西,然后正巧想试一下把core的应用程序发布到Linux,毕竟跨平台.尝试一下 ...

  4. Unix系统级I/O

    在Unix系统中,一且皆为文件.一个Linux文件就是一个字符序列,并且所有的I/O设备都被模型化成了文件.而所有的输入输出都被当作对对应文件的读和写.Linux提供了一组简单.低级的接口,使得所有的 ...

  5. spark实验(二)--scala实验(3)

    实验1,计算级数: 首先打开安装完scala ide的eclipse,在eclipse 中新建一个scala project. 然后新建一个scala的object对象 导入scala.io.StdI ...

  6. ubuntu16.04安装node.js、npm

    ubuntu16.04安装node.js.npm1.请尽量避免在 Ubuntu 上使用 apt-get 来安装 node.js, 如果你已经这么做了,请手动移除: sudo apt-get purge ...

  7. Linux 下忘记mysql 密码

    ERROR (): Access denied for user 'root'@'localhost' (using password: YES). 一.停止 mysql 数据库 /etc/init. ...

  8. Update(Stage4):sparksql:第5节 SparkSQL_出租车利用率分析案例

    目录: 1. 业务2. 流程分析3. 数据读取5. 数据清洗6. 行政区信息 6.1. 需求介绍 6.2. 工具介绍 6.3. 具体实现7. 会话统计 导读 本项目是 SparkSQL 阶段的练习项目 ...

  9. main函数递归

    以前听说main()不能递归?于是在CentOS7上使用gcc-8.1.0测试了一下,发现可行: #include <stdio.h> int x = 5; int main(int ar ...

  10. Python爬虫解析网页的4种方式 值得收藏

    用Python写爬虫工具在现在是一种司空见惯的事情,每个人都希望能够写一段程序去互联网上扒一点资料下来,用于数据分析或者干点别的事情. ​ 我们知道,爬虫的原理无非是把目标网址的内容下载下来存储到内存 ...