通过非const指针修改const方法中的self到self

时间:2014-02-26 21:31:33

标签: c++ const

在下面的示例中,const对象可以通过const方法修改自身,因为在该方法中,它通过non-const指针访问自身。 (same program on ideone

#include <iostream>

struct Object;

Object * g_pObject;

struct Object
{
    Object():m_a(0){}

    void ModifySelfViaConstMethod() const
    {
        g_pObject->m_a = 37;
    }

    int m_a;
};

int main()
{
    Object o;
    g_pObject = &o;

    const Object & co = o;
    std::cout << co.m_a << "\n";
    co.ModifySelfViaConstMethod();
    std::cout << co.m_a << "\n";

    return 0;
}

我对阅读c ++标准不太满意,所以我在这里问:

标准对此有何看法?

a)const方法不保证您在执行此类操作时保持对象不会被修改

b)是否定义明确,必须编译

c)其他?

4 个答案:

答案 0 :(得分:3)

当您声明const函数时,它是“为了您自己的利益”。

换句话说,你声明它为const,因为根据你的初始设计,它不应该改变在运行时调用它的任何对象。

如果在执行此函数的某个稍后阶段你最终更改了对象,编译器将“对你大吼大叫”,告诉你这是错误的。

当然,只有在this上应用时,编译器才能识别此类尝试。

在给定的示例中,编译器无法识别问题,因为它需要在thisg_pObject之间进行比较,并且此类比较只能在运行时进行。

答案 1 :(得分:3)

当方法声明为const时,编译器会确保this指针指向的实例不会被修改。如果您尝试修改this实例,则编译器将失败。但是,编译器无法知道g_pObjectthis实际上指向同一个实例。这需要进行运行时比较,并且没有编译器会浪费时间执行const方法内部使用的每个指针的运行时比较,因为它们可能匹配的可能性很小this指针。因此,如果您要通过外部指针修改Object,则必须进行自己的检查,例如:

void ModifySelfViaConstMethod() const
{
    if (g_pObject != this)
        g_pObject->m_a = 37;
}

答案 2 :(得分:1)

C ++中的稳定性是一种安全工具,而不是安全性。

遵循constancy的代码很可能会按预期工作,并且编译器会提醒所有无意中强制转换constancy的尝试。

如果“我知道自己在做什么”,可以找到各种各样的工具,从const_cast运算符和mutable关键字到平庸的C样式转换。

答案 3 :(得分:1)

  

标准对此有何看法?

它表示(释义)this具有类型const Object *,因此您无法通过this直接修改成员或调用非const成员函数。它没有说明你可以对函数可能访问的任何全局变量做什么;它只控制对调用函数的对象的直接访问。

  当您执行此类操作时,

const方法无法保证您的对象不会被修改

不,不。它声明该函数不会修改对象的意图,并提供一些防止意外破坏该意图的保护。它不会阻止一个适当的疯狂程序员使用const_cast,或(通过这里)通过全局变量进行不受控制的耦合来打破承诺。

  

是否已明确定义且必须编译

是。 o本身并不是常数,所以没有什么可以阻止你采用非常量指针或引用它。成员函数上的const仅限制通过this访问对象,而不是通过其他指针访问任意对象。