姬長信(Redy)

c – 修改* this而不使用const_cast的Const方法


在我正在编写的程序中出现了以下模式.我希望它不是太做作,但它设法在const方法Foo :: Questionable()const中改变一个Foo对象,而不使用任何const_cast或类似的东西.基本上,Foo存储对FooOwner的引用,反之亦然,在Questionable()中,Foo设法通过在其所有者上调用mutate_foo()来修改const方法.问题遵循代码.
#include "stdafx.h"
#include 
using namespace std;

class FooOwner;

class Foo {
    FooOwner& owner;
    int data;

public:
    Foo(FooOwner& owner_, int data_)
        : owner(owner_),
          data(data_)
    {
    }

    void SetData(int data_)
    {
        data = data_;
    }

    int Questionable() const;       // defined after FooOwner
};

class FooOwner {
    Foo* pFoo;

public:
    FooOwner()
        : pFoo(NULL)
    {}

    void own(Foo& foo)
    {
        pFoo = &foo;
    }

    void mutate_foo()
    {
        if (pFoo != NULL)
            pFoo->SetData(0);
    }
};

int Foo::Questionable() const
{
    owner.mutate_foo();     // point of interest
    return data;
}

int main()
{
    FooOwner foo_owner;
    Foo foo(foo_owner, 0);      // foo keeps reference to foo_owner
    foo_owner.own(foo);         // foo_owner keeps pointer to foo

    cout 

这是定义的行为吗? Foo :: data应该被声明为可变吗?或者这是一个标志我做的事情是致命的错误?我正在尝试实现一种只在请求时设置的延迟初始化’数据’,并且下面的代码编译得很好而没有警告,所以我有点紧张我在UB土地.

编辑:Questionable()上的const只使直接成员为const,而不是对象指向或引用的对象.这会使代码合法吗?令我感到困惑的是,在Questionable()中,它具有类型const Foo *,并且在调用堆栈的下方,FooOwner合法地具有用于修改Foo的非const指针.这是否意味着可以修改Foo对象?

编辑2:也许是一个更简单的例子:

class X {
    X* nonconst_this;   // Only turns in to X* const in a const method!
    int data;

public:
    X()
        : nonconst_this(this),
          data(0)
    {
    }

    int GetData() const
    {
        nonconst_this->data = 5;    // legal??
        return data;
    }
};