C++ 常量成员函数

C++ 常量成员函数,c++,constants,C++,Constants,const member函数保证成员函数不能更改任何成员变量,除非它们被标记为可变的 这么说来,它不能保证其他任何东西吗 这里是一个真实的例子。我有一个类EventHandler和EventDispatcher class EventHandler { public: void registerHandler(EventHandler* handler) const // Should this be a const? { EventDispatcher::regis

const member函数保证成员函数不能更改任何成员变量,除非它们被标记为可变的

这么说来,它不能保证其他任何东西吗

这里是一个真实的例子。我有一个类
EventHandler
EventDispatcher

class EventHandler
{
public:
   void registerHandler(EventHandler* handler) const   // Should this be a const?
   {
      EventDispatcher::registerHandler(handler);
   }
};

EventDispatcher   // Singleton Class
{
public:
   void registerHandler(EventHandler* handler)
   {
      mListeners.push_back(handler);
   }

private:
   std::vector<EventHandler*> mListeners;
};
类事件处理程序
{
公众:
void registerHandler(EventHandler*handler)常量//这应该是常量吗?
{
EventDispatcher::registerHandler(处理程序);
}
};
EventDispatcher//Singleton类
{
公众:
无效注册表句柄(EventHandler*句柄)
{
姆利斯特。推回(处理者);
}
私人:
std::矢量多址侦听器;
};
EventDispatcher
registerHandler(EventHandler*)
应该是常量吗?它不会更改其成员变量,但会更改全局状态。

方法声明后面的const关键字能保证什么? 担保是合同提醒,而不是“物理”记忆障碍

因此,如果您正确实现
const
关键字,编译器将能够帮助您检测可能的bug

但是,没有C/C++编译器会阻止您直接修改成员国;既不是通过字段,也不是通过将对象引用强制转换为指针并修改底层内存

是否允许我的const方法更改(本地/全局)状态?
const
方法不允许更改系统的外部行为,但是
const
方法完全可以更改内部状态

换句话说,在随机调用了两次所有
const
方法之后,系统仍然应该提供与最初相同的行为

另一方面,如果
const
方法想要缓存一个耗时的计算并在下次调用中重用它,那么应该允许它。记录统计信息但不改变系统行为的logger类也是如此。

方法声明后面的const关键字能保证什么? 担保是合同提醒,而不是“物理”记忆障碍

因此,如果您正确实现
const
关键字,编译器将能够帮助您检测可能的bug

但是,没有C/C++编译器会阻止您直接修改成员国;既不是通过字段,也不是通过将对象引用强制转换为指针并修改底层内存

是否允许我的const方法更改(本地/全局)状态?
const
方法不允许更改系统的外部行为,但是
const
方法完全可以更改内部状态

换句话说,在随机调用了两次所有
const
方法之后,系统仍然应该提供与最初相同的行为


另一方面,如果
const
方法想要缓存一个耗时的计算并在下次调用中重用它,那么应该允许它。记录统计信息但不改变系统行为的logger类也是如此。

正确,它不保证对象本身以外的任何其他状态。我想说的是,并没有特别的要求它不修改全局状态。[如果走极端,任何函数调用都会修改处理器的当前状态,即使它只是将返回地址存储在堆栈上[1]]

但更合理的做法是,像这样的
const
成员函数:

 class myclass
 {
 private:
    std::vector<int> v;
 public:
    std::vector<int> getV() const { return v; }
 };
class-myclass
{
私人:
std::向量v;
公众:
std::vector getV()常量{return v;}
};
这将创建向量
v
-的副本,该副本反过来分配内存(从而更改全局状态)。将对象提供给输出流的输出函数也是类似的

如果一个成员函数修改了一些全局状态(以一种不明显的方式),那么可能应该在函数的描述中明确说明(文档有时很有用)

(1)当然,C++和C标准并没有声明处理器必须有一个栈、返回地址等——编译器可以内嵌所有代码,而不做任何“调用”,或者用魔法“记住”在何处返回-只要魔法真的起作用,就可以依赖它。 根据已编辑的问题进行编辑:

这是在两个方向上都不完全明显的一种,您可能希望
registerhandler
执行类似于“将处理程序对象存储在某处”的操作。但由于它并没有修改对象本身,这可能有助于解释它正在更新dispatcher类。当然,如果它实际上没有更新类本身,或者没有使用类中的任何内容,那么您可能应该将其设置为
静态
,而不是
常量
——这样很明显,它实际上没有修改对象本身


旁白:在编写时,您的代码无法工作,因为
EventDispatcher::registerHandler
不是静态成员,并且您的
EventHandler::registerHandler
没有引用
EventDispatcher
的实例。您必须将
EventDispatcher
的实例作为全局变量,或者将
EventDispatcher::registerHandler
作为静态函数,并将
mListeners
作为静态成员。或者其他类似的东西

正确,它不保证对象本身以外的任何其他状态。我想说的是,并没有特别的要求它不修改全局状态。[如果走极端,任何函数调用都会修改处理器的当前状态,即使它只是将返回地址存储在堆栈上[1]]

但更合理的做法是