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