2

这是我拥有的代码

class A
{
public:
    void Func1() const;
};

class B
{
public:
    A* a;
    void Func2() const
    {
        // do something with 'a'
    }
};

void A::Func1() const
{
    B b;
    b.a = this;
    b.Func2();
}

现在显然这给了我一个错误,因为我试图从 const 转换为 non-const。

b.a = this;

有什么方法可以调用Func2而不必抛弃this. 因为Func2无论如何都是一个 const 函数,所以它不会改变this.

4

4 回答 4

3

您必须将其声明A*为 const:

class A
{
public:
    void Func1() const;
};

class B
{
public:
    const A* a;
    void Func2() const
    {
        // do something with 'a'
    }
};

void A::Func1() const
{
    B b;
    b.a = this;
    b.Func2();
}

由于 in A::Func1this指针是 const。

于 2012-05-17T12:14:16.630 回答
1

Func2可能不会改变this,但b.a不会const改变,之后您可以自由更改。没有正确的方法可以做到这一点,尽管存在解决方法,例如mutableor const_cast

这是错误设计的标志。

于 2012-05-17T12:14:19.570 回答
1

是的,使A *常数:

class B {
public:
    const A *a

...
};
于 2012-05-17T12:14:40.713 回答
1

如果class B总是*a作为一个const对象使用,那么正如其他人所说,只需将声明更改为

public: const A* a

在这一点上,我应该提一下, 的常量B::Func2是一条红鲱鱼,因为它与 的常量完全没有关系B::a。这意味着不允许更改 ; 的B::Func2值。但是,允许取消引用和改变结果对象。constaa

现在,如果相对于class B两者都有操作const和非const操作,*a那么您的类设计需要更改。class B如果您切换到使用上面的 a会更好const A* a,并添加另一个class D : public B封装所有变异操作的方法。另外,a应该隐藏在一个属性设置器后面;这使您可以执行以下操作

class B {
    const A* a;
public:
    void setA(const A* a) { this->a = a; }
    void Func2() const {}
};

class D : public B {
    A* a;
public:
    using B::setA;
    void setA(A* a) { 
        this->a = a;
        static_cast<B*>(this)->setA(const_cast<const A*>(a));
    }
    void Func3() { /* do something to D::a */ }
};

With this scheme both B and D keep independent, suitably typed pointers to the object to be accessed. If setA is called on a B, or on a D with a const A* parameter then only B::a is set. If setA is called on a D with an A*, then both B::a and D::a are properly set. This has become possible because by abstracting the member behind a setter you can then overload the setter on the constness of its parameter.

于 2012-05-17T12:25:20.780 回答