最近在看Effective C++,那么问题来了

王大贵 2014-11-10 01:20:07
Effective C++ 条款6:
不想使用编译器提供的默认函数,就该明确拒绝


书上举例,一个class Home{..};如果希望他不具备复制的功能,应该声明一个显示的复制函数,然后这个复制函数位于private,然后不去定义这个复制函数。这样就可以防止对象的复制


~~~啊~~~


在看这本书以前,我遇到过类似的问题,一个类class Video{...};这是一个模拟唱片的类
这个类要求不能被复制,也不能用=号,(唱片为只读)然后我当时采用的办法是定义一个=重载,然后什么都不做
public:
firend void operator=(const Video&) //声明,在共有部分

void Video::operator=(const Video&) //定义,这个函数什么都没做
{
std::cout<<"唱片为只读模式,无法复制内容\n"
}
我的想法是:当用户执行了一个误操作(复制),程序给出提示并阻止他,而不是让程序出错

当时我使用这个类的时候没遇到什么问题,然后今天看了Effective C++提供的方法,我想问下,我的这种处理是否存在潜在的风险
...全文
221 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
王大贵 2014-11-11
  • 打赏
  • 举报
回复
引用 13 楼 bear234 的回复:
书上没有说错 如果你要禁止复制或者赋值 就因该明确把复制构造函数和operator = 函数声明成private 如果你想提示什么错误 也可以 不过呢,唯一需要注意的就是:你真的明白禁止复制意味着什么吗?意味着这个类不能做函数的参数和返回值了
没什么太大问题吧,一个被禁止复制的类,可以用引用传给函数,也可以返回引用
mujiok2003 2014-11-11
  • 打赏
  • 举报
回复
引用 13 楼 bear234 的回复:
如果你想提示什么错误 也可以 不过呢,唯一需要注意的就是:你真的明白禁止复制意味着什么吗?意味着这个类不能做函数的参数和返回值了
nah,只是关闭值语义。 lz的做法是错的。
bear234 2014-11-11
  • 打赏
  • 举报
回复
书上没有说错 如果你要禁止复制或者赋值 就因该明确把复制构造函数和operator = 函数声明成private 如果你想提示什么错误 也可以 不过呢,唯一需要注意的就是:你真的明白禁止复制意味着什么吗?意味着这个类不能做函数的参数和返回值了
mujiok2003 2014-11-10
  • 打赏
  • 举报
回复
书上的做法是编译器错误, 这个错误由程序员纠正, 而你的错误在运行试给出的, 直接到了用户那里: 1. 不是所有用户的都能力纠错 2. 写一条日志也算不是一种友好的提醒。 3. “不可拷贝”既然个需求,你的程序代码中就不该试图拷贝它,这个属于错误实现。
ForestDB 2014-11-10
  • 打赏
  • 举报
回复
按照7L的例子,LZ关注的和条款的关注点并不相同。
bobo_包子 2014-11-10
  • 打赏
  • 举报
回复
引用 8 楼 zhcosin 的回复:
你要搞清楚的一点是:你是希望编译器拒绝程序员写出这样的代码,还是你的程序拒绝用户做出这样的操作。
是这个道理
碼上道 2014-11-10
  • 打赏
  • 举报
回复
你要在编译阶段就要拒绝
zhcosin 2014-11-10
  • 打赏
  • 举报
回复
你要搞清楚的一点是:你是希望编译器拒绝程序员写出这样的代码,还是你的程序拒绝用户做出这样的操作。
王大贵 2014-11-10
  • 打赏
  • 举报
回复
引用 4 楼 zmlovelx 的回复:
明确拒绝使用,是为了防止代码中出现这样的用法。 编译过程就会拒绝, 你的做法是不正确的。相当于把错误的方法引入到了代码中去。
可能我的序言表达有问题吧。 举个例子:你去银行转账,正常情况下你想XX账号转去了一些钱,那你这个”转账“的操作属于正常操作 然后XX账号由于一些原因被冻结了。 这时你再执行”转账“操作,你的转账不会被执行,同事银行系统会提示:转账失败,原先:XX账号已被冻结。 我这个类是就是想达到这样一个功能,用户希望复制对象(就是往里面写歌曲),然后程序拒绝了用户的这个操作要求,然后提示用户:你的此次操作未成功,因为这是一张只读唱片
ri_aje 2014-11-10
  • 打赏
  • 举报
回复
firend operator=,确定这能编译? 要禁止复制赋值,用 delete 函数就最好了。

struct a_test
{
 a_test (a_test const&) = delete;
 void a_test (a_test const&) = delete;
};
幻夢之葉 2014-11-10
  • 打赏
  • 举报
回复
不一样,你的方法只能在运行时候才给出提示! 使用private方法是你在编译时期就指出! 明确告诉使用者这个类的对象不能进行拷贝! 最典型的例子就是C++的输入输出流(不能拷贝和赋值),另外还有一个就是单实例模型(构造,赋值,拷贝声明为私有)!
帅得不敢出门 2014-11-10
  • 打赏
  • 举报
回复
明确拒绝使用,是为了防止代码中出现这样的用法。 编译过程就会拒绝, 你的做法是不正确的。相当于把错误的方法引入到了代码中去。
王大贵 2014-11-10
  • 打赏
  • 举报
回复
引用 1 楼 u013163178 的回复:
我理解是这样的,不知道对不对: 重载=只能防止被赋值,不能保证不拷贝构造啊,有些地方的拷贝不需要=号,比如说非引用传递参数啊,或者返回局部变对象。
可能我描述的不是很清楚,拷贝构造函数我也声明了一个,定义和那个=号类似,在函数体内没有实质性的代码 Video::Video(const Video& A) { std::cout<<"这是一张只读唱片,无法写入内容.\n"; }
铖邑 2014-11-10
  • 打赏
  • 举报
回复
没必要用firend 吧
li4c 2014-11-10
  • 打赏
  • 举报
回复
我理解是这样的,不知道对不对: 重载=只能防止被赋值,不能保证不拷贝构造啊,有些地方的拷贝不需要=号,比如说非引用传递参数啊,或者返回局部变对象。

64,683

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧