C++11通过拷贝构造器拷贝const字段(待解决)
问题梗概如标题所述。
在今天实现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字段(待解决)的更多相关文章
- C/C++(C++拷贝构造器,赋值运算符重载)
拷贝构造器 由己存在的对象,创建新对象.也就是说新对象,不由构造器来构造,而是由拷贝构造器来完成.拷贝构造器的格式是固定的. class 类名 { 类名(const 类名 & another) ...
- [c++基础]3/5原则--拷贝构造函数+拷贝赋值操作符
/* * main.cpp * * Created on: Apr 7, 2016 * Author: lizhen */ #include <iostream> #include &qu ...
- Win7 64位 + LoadRunner 11录制时弹不出IE的解决办法 Win7 64位 + LoadRunner 11录制时弹不出IE的解决办法
Win7 64位 + LoadRunner 11录制时弹不出IE的解决办法 Win7 64位 + LoadRunner 11录制时弹不出IE的解决办法 1. 卸载IE9( 装了Win7 64位后,默认 ...
- 拷贝构造函数和const成员函数
实验原因 说明如何使用const描述保护类数据不会意外修改. 编译环境 vc6sp6 + win7x64 工程下载 copyConstruction_constMemberFunction.zip ...
- C++11如何减少内存拷贝次数
C++11中出现了很多迷人的特性.例如智能指针实现高效的内存管理,std::bind和std::function函数封装器,以及lambda实现的函数对象语法糖,都是使我着迷的地方. 而C++11最大 ...
- C++ 拷贝构造函数之const关键字
class Complex { public: //拷贝构造函数1 Complex(const Complex &c); //拷贝构造函数2 Complex(Complex &c); ...
- 拷贝构造函数 & 拷贝赋值运算符
一.拷贝构造函数 1. 形式 class A { public: // ... A(const A &); // 拷贝构造函数 }; 2. 合成拷贝构造函数 编译器总会为我们合成一个拷贝构造函 ...
- Installshield更新时,新加dll未拷贝至安装目录问题完美解决【原创】
最近在发现在开发过程中新增的目录或文件(特别是dll\ocx\exe等二进制文件),在升级安装时拷贝失败. 经过一周的研究,完美解决办法: 对于新增的文件或目录,放到一个新的component中,并且 ...
- Python 关于拷贝(copy)汇总(列表拷贝 // 字典拷贝 // 自定义对象拷贝)
1.列表拷贝 引用是指保存的值为对象的地址.在 Python 语言中,一个变量保存的值除了基本类型保存的是值外,其它都是引用,因此对于它们的使用就需要小心一些.下面举个例子: 问题描述:已知一个列表, ...
随机推荐
- API接收数据反序列化失败问题查找
C# API接收到数据后,反序列化后直接返回null,而不会给出错误提示,所以不好排查错误. 通过在api中直接进行反序列化,能够得到错误明细: 没有报错的时候,request会直接为null,不会报 ...
- js中的文本编辑器控件KindEditor
使用文本编辑器控件KindEditor渲染文本域页面显示 this.sync()同步KindEditor的值到textarea文本框 editor.isEmpty()判断文本域是否是空 editer. ...
- C# 篇基础知识9——特性、程序集和反射
特性(Attribute)是用于为程序元素添加额外信息的一种机制.比如记录文件修改时间或代码作者.提示某方法已经过期.描述如何序列化数据等等.方法.变量.属性.类.接口.结构体以及程序集等都是程序元素 ...
- iOS 音视频播放
播放控制切换为: ijkplayer wiki: https://github.com/changsanjiang/SJVideoPlayer/wiki/Use-ijkplayer 播放控制切换为: ...
- AD10如何新建一个集成库
1.新建一个集成库工程 2.添加原理图库 3.添加封装库 4.最关键的一步:对这个工程需要进行编译 5.在界面的右边就能看到自己建的封装库了
- The Preliminary Contest for ICPC Asia Shanghai 2019 B Light bulbs (离散的差分)
复杂度分析,询问一千次,区间长1e6,O(1e9)超时. 那么我们知道对于差分来说,没必要一个一个求,只需要知道区间长就可以了,所以我们定义结构体差分节点,一个头结点,一个尾节点. 这样tail.lo ...
- ES6-对象的简写方式
var name = 'tom'; var age = 11; //es5定义对象 var obj = { name:name, age ...
- 【C语言】编写程序,输出以下图形
编写程序输出以下图形: * ** *** **** ***** 代码: #include <stdio.h> int main() { int i, j; ; i <= ; i++) ...
- Shiro入门学习与实战(一)
一.概述 1.Shiro是什么? Apache Shiro是java 的一个安全框架,主要提供:认证.授权.加密.会话管理.与Web集成.缓存等功能,其不依赖于Spring即可使用: Spring S ...
- 腾讯云Windows Server下nodejs websocket ssl配置
1.从腾讯云申请SSL证书,下载解压,得到如下文件: 2.nodejs代码: // wss.js const fs = require('fs'); // 一些配置信息 const cfg = { p ...