我可以为const和非const实例写不同的copyCtor吗? [英] Can I write different copyCtor for const and non-const instances?

查看:157
本文介绍了我可以为const和非const实例写不同的copyCtor吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下问题:

我有一个类应该这样做:

I have a class which should do this:

Obj o;
Obj o1(o), o1=o; // deep-copies
const Obj c(o), c=o; // deep-copies
const Obj c1(c), c1=c; // shallow-copies
Obj o2(c), o2=c; // deep-copies

我该如何做到这一点, (我的意思是我会做 Const_obj 继承 Obj 否则。)

How can I do this preferably without inheritance? (I mean I would do Const_obj inheriting from Obj otherwise.)

编辑:

直接使用 o.clone()不是一个选项,

Using o.clone() directly is not an option because then I could easily introduce bugs by accidentally not cloning.

编辑:

最后,一个适当的,完整的解决方案,使用从有效的C ++由Scott Meyers 的想法的延迟评估。

Finally, there is a proper, complete solution with lazy evaluation using the idea from Effective C++ by Scott Meyers. Check out my answer below.

推荐答案

阅读有效C ++作者Scott Meyers 之后,以下是解决方案:

After reading Effective C++ by Scott Meyers, the following is a solution:

定义一个模板,执行惰性求值(使用引用计数):

define a template which does a lazy evaluation (with reference counting):

class Obj : private lazy<Obj_data>{};

,惰性存储Obj_data为私有,具有受保护的访问器,一个用于修改,一个用于只读访问。

修饰符访问器首先深层复制 Obj_data (如有必要),然后移交对数据的引用。只读存取器只是返回一个const引用。

and the lazy stores the Obj_data privately, has protected accessors, one for modification, one for read-only access.
The modifier accessor first deep-copies the Obj_data if necessary, then hands over the reference to the data. The read-only accessor just returns a const reference.

它的总成本是存储2个额外的指针(一个用于数据,一个用于计数器) 。

The overall cost of this is storing 2 extra pointers (one for the data and one for the counter) and a counter.

实现方式如下:

class lazy{
protected:
  lazy(const lazy&obj){lazy_copy(obj);}
  //(the required constructors, operator= ...)

  // accessors:
  const Obj_data& data() const {return *od;}
  Obj_data& mod_data() {make_private(); return *od;}
private:
  void lazy_copy(const lazy& obj);
  void make_private(); // this does the actual deep-copy, as late as possible.
private:
  counter*;
  Obj_data* od;
};

因此,读取和修改 Obj go

So, reading and modifying an attribute of Obj goes

void Obj::method(){
   cout << data().some_attribute;    // simple read
   mod_data().i = 10;                // simple modify
   const Obj_data& const_d = data(); // assignable for lots of read-outs
   Obj_data& var_d = mod_data();     // assignable for lots of modifications.
}

请注意,您只能使用 data / code>在 const 中作为 mod_data()是类中的一个非const函数,所以这个解决方案是完全安全的,只需很少的开销。

Note that you can only use data() in a const member as mod_data() is a non-const function in the class, so this solution is completely safe with little overhead.

理论背景:问题中所需的行为是一个实现细节,不涉及客户端。因此,我们通过私人继承来解决它。

Theory background: the desired behaviour in the question is an implementation detail, does not concern the client. Therefore we solve it by private inheritance.

这篇关于我可以为const和非const实例写不同的copyCtor吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆