这是我的代码
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;
有没有办法在不抛弃this
的恒常性的情况下调用Func2
.由于Func2
无论如何都是常量函数,因此它不会更改this
。
您必须将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();
}
因为在A::Func1
中,this
指针是常量。
如果class B
总是将*a
作为const
对象使用,那么正如其他人所说,只需将声明更改为
public: const A* a
在这一点上,我应该提到B::Func2
的恒定性是一条红鲱鱼,因为它与B::a
的恒定性完全没有关系。B::Func2
const
意味着不允许更改a
的值;但是,允许取消引用a
并改变生成的对象。
现在,如果class B
在*a
方面同时具有const
和非const
操作,那么您的类设计需要更改。如果您切换class B
使用上述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 */ }
};
使用此方案,B
和 D
都保持独立的、适当类型的指向要访问的对象的指针。如果在B
或具有const A*
参数的D
上调用setA
则仅设置B::a
。如果在具有A*
的D
上调用setA
,则B::a
和D::a
都设置正确。这已经成为可能的,因为通过抽象 setter 后面的成员,您可以在其参数的恒定性上重载 setter。
Func2
可能不会更改this
,但b.a
不是const
,之后您可以自由更改它。没有正确的方法可以做到这一点,尽管存在解决方法,例如 mutable
或 const_cast
.
这是设计错误的标志。
是的,使A *
常量:
class B {
public:
const A *a
...
};