2013-05-12 66 views
0

当我编写课程时,是否使不变的类或仅使用const关键字是一个大问题。不可变的数据结构或const变量?

我来自Objective-C,当我使用Objective-C时,有分离的可变/不可变约定。这主要是因为在C++中缺少const语义,但它也保证了对象的不可变性,尤其是当不可变对象被复制到可变对象时,我可以捕获它。所以我可以将共享状态用于不可变对象,并且只在将状态复制到可变对象时才复制状态。

在C++中,有const语义,所以我试图用它设计一个容器,但我有一些问题。这里是示例代码。

struct Foo 
{ 
    int bar; 
}; 

Foo const f1; 
Foo f2 = f1; // This is allowed but... 

拷贝赋值从f1f2是允许的,并没有任何警告或错误。问题是我无法捕捉将不可变对象复制到可变对象的情况。当我编写一个复制分配构造函数时,它适用于可变对象或不可变对象。我想让不可变对象使用共享状态,并且只有当它被复制到可变对象时才会被复制。

复制写入不适合我,因为我的容器代码应该适用于实时程序。表现击中必须可见并且位置应该是可预测的。写入时复制是不允许的,因为它将复制成本推迟到不可预知的时间点。复制成本必须可见。

这可以通过为每个不可变/可变对象创建分隔对象来解决,但我不确定这是否是C++中的好设计。

什么是推荐的模式,使可变的复制成本不可变/可变类?我认为这可以解决,如果我可以使一些复制构造从不可变到可变,但我找不到任何方法。

+1

你可能不应该实现这两个。我只是用const语义实现mutable,然后让用户将它包装在shared_ptr中,如果他们想阻止副本的话。 – Pubby 2013-05-12 03:29:53

回答

1

随着指针:

const Foo *f1 = new Foo(); /* Foo instance is trapped in pointer-to-const */ 
//Foo *f2 = f1; /* Error; not allowed without cast. */ 
Foo *f3 = new Foo(*f1); /* Use copy constructor */ 
delete f1; 
delete f3; 

随着shared_ptr的(C++ 11):

#include <memory> 

std::shared_ptr<Foo> f1 = std::make_shared<Foo>(); /* shared_ptr will not implicitly copy object */ 
std::shared_ptr<Foo> f2 = f1; /* No copy made */ 
std::shared_ptr<Foo> f3 = std::make_shared<Foo>(*f1); /* use copy constructor */ 

如果客户端使用对象直接,他们采取用于复制的开销的责任。这或多或少是预期的。您可以在课堂上内部使用指针/ refcounting/copy-on-write来隐藏开销,但正如您所说,这不是您想要的。