【发布时间】:2012-01-09 19:02:45
【问题描述】:
我试图更好地理解const-correctness 是如何工作的,更具体地说,在处理其成员基于containers 和smart pointers 的类时。
我猜const-correctness 属性是相同的,无论类成员如何。但是,由于我很难清楚地了解发生了什么,
我决定征求你的意见。
所以,这里是上下文。我有一个ShapeContainer 类,它有一个智能指针向量作为私有类成员。
Shape 类是抽象的,具有以下虚函数 virtual float doSomething();,然后由其派生类重新定义。请注意,它是一个非常量类函数。
相关部分代码如下:
class ShapeContainer{
public:
typedef std::shared_ptr<Shape> ShapePtr;
typedef std::vector<ShapePtr> ShapePtrContainer;
// .......
const ShapePtr & operator[]( int ) const { return m_vect[index]; }; // const version
// ShapePtr & operator[]( int ) { return m_vect[index]; }; // non-const version
// .......
private:
ShapePtrContainer m_vect;
};
class Shape{
public:
// ...
virtual float doSomething() = 0;
};
这是我的问题。
第一季度。为什么我可以通过以下方式调用doSomething() 函数:int index = 0; float tmp = container1[index]->doSomething();(具有ShapeContainer container1=createBasicShapes();)?
据我了解,在调用const ShapePtr operator[] const 函数后,我们将得到一个const 指向Shape 对象的指针,但是doSomething() 是虚拟的
函数是不是 const。那么,对 const 对象的引用如何调用非 const 函数呢?
第二季度。通过调用 doSomething() 函数,如前所述 (float tmp =container1[index]->doSomething();)和通过添加 operator[] 的 non-const 版本,此 latter
然后调用重载版本而不是const-version。为什么会这样?
现在,我不再拥有 ShapeContainer 类,而是创建了一个名为 ShapeContainerInfo 的新类,它仍然有一个 vector,但属于中间 ShapeInfo 类(它有一个智能指针作为类成员)。
class ShapeContainerInfo{
public:
typedef std::vector<ShapeInfo> ShapeContainer;
const ShapeInfo & operator []( int index) const { return m_vect[index]; };
// ShapeInfo & operator []( int index) { return m_vect[index]; }; // non-const version
private:
ShapeContainer m_vect;
};
class ShapeInfo{
public:
typedef std::shared_ptr<Shape> ShapePtr;
// ...
float doSomething(){ return m_ShapePtr->doSomething(); };
private:
ShapePtr m_ShapePtr;
int m_nID;
};
第三季度。当我调用float tmp = container2[i].doSomething(); 时,我收到以下编译器错误:error C2662: 'ShapeInfo::doSomething' : cannot convert 'this' pointer from 'const ShapeInfo' to 'ShapeInfo &'。
但是,当我添加重载operator [] 的non-const 版本时,编译器错误消失了。那么,为什么我真的需要 non-const operator[] 来代替 ShapeContainerInfo 而不是 ShapeContainer?
第四季度。如果ShapeContainerInfo 的m_vect private 成员现在设置为public 成员并且仅 定义了operator[] 的常量版本(不是non-const 之一),那么没有编译器错误消息。为什么这个?例如将m_vect设置为公共类成员后:float tmp = info.m_vect[i].doSomething();
Q5。如何正确定义ShapeInfo 和ShapeContainerInfo 类,这样我只需要定义operator[] 的const-version 并且仍然能够调用float doSomething() 函数?
对整个示例代码感兴趣的人,请找到它here。
澄清,建议总是受欢迎的:-)
谢谢!
【问题讨论】:
标签: c++ polymorphism containers smart-pointers const-correctness