Mark B介绍了基本思考方法,但需要注意的是,您可以在纯C++中进行类似操作。例如:
struct Data { };
class ConstImage {
protected:
const Data *const_data;
public:
ConstImage (const Data *cd) : const_data(cd) { }
int getFoo() const { return const_data->getFoo(); }
};
class Image : public ConstImage {
protected:
Data *data() { return const_cast<Data *>(const_data); }
public:
Image(Data *d) : const_data(d) { }
void frob() { data()->frob(); }
};
不要使用const Image *
,而是使用ConstImage *
,就这样。您还可以简单地定义一个静态函数伪构造函数:
const Image *Image::newConstImage(const Data *d) {
return new Image(const_cast<Data*>(d));
}
当然,这是建立在程序员确保没有任何可能会改变指向的Data状态的const函数的前提下的。
你还可以结合这些技术:
class Image {
protected:
const Data *const_data;
Data *data() { return const_cast<Data *>(const_data); }
public:
void frob() { data()->frob(); }
int getFoo() const { return const_data->getFoo(); }
Image(Data *d) : const_data(d) { }
static const Image *newConst(const Data *cd) {
return new Image(const_cast<Data *>(cd));
}
};
这样做既兼顾了两种优势。由于
data()
是一个非const成员,因此可以对所指向的值进行静态检查以实现变异。同时,您还具有const构造函数,并且可以直接在
Image *
和
const Image *
之间转换(即,如果您知道它是安全的,则可以删除const)。您还可以进一步抽象出指针的分离。
template<typename T>
class ConstPropPointer {
private:
T *ptr;
public:
ConstPropPointer(T *ptr_) : ptr(ptr_) { }
T &operator*() { return *ptr; }
const T &operator*() const { return *ptr; }
T *operator->() { return ptr; }
const T *operator->() const { return ptr; }
};
class Image {
protected:
ConstPropPointer<Data> data;
public:
void frob() { data->frob(); }
int getFoo() const { return data->getFoo(); }
Image(Data *d) : data(d) { }
static const Image *newConst(const Data *cd) {
return new Image(const_cast<Data *>(cd));
}
};
现在,如果
this
是const,那么
data
也会变成const,并且将此传播到
* data
中。 对你来说够好吗? :)
我想最终的答案可能是:为了使const构造函数有用且安全,我们需要像内置于语言中的
ConstPropPointer
一样的东西。 然后,允许const构造函数从
const T *
分配给
constprop T *
。 这比听起来要复杂得多 - 例如,这如何与
vector
等模板类交互?
因此,这是一个相当复杂的更改,但似乎问题并不常见。 更重要的是,这里有一个简单的解决方法(
ConstPropPointer
可以作为库使用,并且静态伪构造函数足够简单)。 因此,如果它被提出,C ++委员会可能会将其排除在更重要的事情之外。
new const
的情况下使用,就像非const方法不能用于const对象一样。 - Catskulconst int x = 6
这样的操作时,您初始化x
- 而不是修改它。上面是一个糟糕的例子,但是const构造函数应该存在,并且它们在其他应用程序中将非常有用。 - mip