常量成员函数可以修改数据成员
const member function can modify data member
问题:为什么常量成员函数有时可以修改数据成员,有时不能?
解释:下面的代码是我工作基线中工作代码的摘录。
我有一个计算器类,它拥有一个名为"theLayout"的数据成员(下面定义的标头和实现)。计算器类有一个名为"Parms()"的常量成员函数,它返回一个智能指针,指向布局拥有的Parms对象(通过调用自己的Parms()函数)。
计算器类有一个名为 calculateStart() 的 const 成员函数,它设置(即修改)在计算器类中调用 Parms() 函数返回的引用。
这似乎与 const 对我来说的含义相矛盾。如果 const 成员函数无法修改 this 指针,那么为什么它可以在它拥有的一个数据成员 (theLayout) 上设置值?这难道不是"修改"计算器实例的 this 指针,从而与 const 成员函数的含义相矛盾吗?这是否有效,因为布局是一个指针?
计算器类
//Header
class Calculator
{
public:
Calculator();
//ParmsPtr is refcounted smart pointer
const ParmsPtr& parms() const {return theLayout->parms();}
protected:
void calculateStart() const; //Why does this work?
//It seems more intuitive that this should be declared as:
void calculateStart() //with no const modifier.
Layout& theLayout;
}
//Implementation
void Calculator::calculateStart() const
{
parms()->setStart(1);
}
布局类
//Header
class Layout : public RefCountedObject
{
public:
Layout();
//ParmsPtr is refcounted smart pointer
inline const ParmsPtr& parms() const;
private:
ParmsPtr theParms;
}
//Implementation
inline const ParmsPtr& Layout::parms() const
{
if (!theParms)
{
Layout* nonConstThis = const_cast<Layout*>(this);
ParmsPtr parms = new Parms();
nonConstThis->setParms(parms);
}
return theParms;
}
计算器类有一个名为 calculateStart() 的 const 成员函数,它设置(即修改)在计算器类中调用 Parms() 函数返回的引用。
是的,calculateStart()
确实修改了计算器对象,考虑到其定义中的最终 const 限定符,这是出乎意料的。
为什么?看看inline const ParmsPtr& Layout::parms() const
的定义;最终const
告诉编译器该函数不会修改Layout
对象,尽管它实际上会修改。如何?通过恶作剧地将对象const_cast
到非常量对象;这就是恒常性被打破的地方,这就是为什么setParms()
可以被召唤。
这是一种不好的做法,尽管可能有一些原因这样做。在这种情况下,const_cast
可以达到此目的。
关键问题是,通过将 start() 声明为 const 究竟是什么? 答案是引用,而不是引用的值。
在您的示例中,在 start() 方法中,编译器将数据成员视为具有 Layout const&,这与 const Layout& 不同。 同样的事情也适用于指针。 如果数据成员是指针类型,编译器会将该类型视为布局 const*。
- 用于访问容器<T>数据成员的正确 API
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 数据成员SFINAE的C++17测试:gcc vs clang
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 如何在c++中定义以struct为数据成员的类中的构造函数
- 静态数据成员模板专用化的实例化点在哪里
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 使用指针访问数组中的对象数据成员
- 友元函数无法访问私有数据成员 (c++)
- 我可以在 C++ 中将数据成员/变量从其定义之外添加到结构中吗?
- 为什么将一个结构的引用设置为等于另一个结构只会更改一个数据成员?
- 将私有数据成员添加到野牛生成的类中
- 输入数据成员未按要求工作
- 在不编写显式 setter 的情况下修改私有类数据成员的便捷方法是什么?模板有用吗?
- 如何仅通过类方法修改类公共数据成员
- 如何在C++中限制对象私有数据成员修改
- 常量成员函数可以修改数据成员
- C++ 如何确保复制构造函数不会修改原始对象的指针数据成员?
- 当我们可以使用普通函数修改静态数据成员时,静态成员函数的需求是什么?
- 为什么这个const成员函数要修改静态成员数据?