在工作中的讨论中,我们似乎无法将“逻辑”const正确性强制应用于具有指针数据成员的类,例如:
可以看出,我们希望
此外,我们希望在管理器的生命周期内使指针引用另一个
当然,在这里强制执行所有“按位”const正确性,因为
我们唯一想到的是向
但是这样做太丑陋了,编译器肯定无法执行。
具体来说,尝试为
有没有一种方法可以实现这个目的?
class Widget {
public:
void Foo();
void FooConst() const;
};
class WidgetManager {
public:
WidgetManager() : _pW(std::shared_ptr<Widget>(new Widget())) { }
void ManagerFoo()
{
_pW->Foo(); // should be OK, will not compile if declared as "const Widget*"
_pW->FooConst(); // should be OK
}
void ManagerFooConst() const
{
_pW->Foo(); // should NOT be OK, will not compile if declared as "const Widget*"
_pW->FooConst(); // should be OK
}
void RegenerateWidget()
{
_pW = std::shared_ptr<Widget>(new Widget());
}
private:
std::shared_ptr<Widget> _pW;
};
可以看出,我们希望
WidgetManager :: ManagerFooConst()
不能调用WidgetManager
指针成员的非const函数,同时仍然允许从其他非const函数中调用。这意味着将指针声明为std :: shared_ptr<const Widget>
(即const Widget*
)是不行的。此外,我们希望在管理器的生命周期内使指针引用另一个
Widget
,因此我们不想将其保留为数据成员(也无法通过引用保存)。当然,在这里强制执行所有“按位”const正确性,因为
WidgetManager
的任何数据成员都不能在const方法内修改(包括由_pW
指向的特定Widget
),但我们希望实现“逻辑”const正确性,即连带指向的成员也不能被修改。我们唯一想到的是向
Widget
添加const和non-const“获取this”的函数:class Widget {
public:
void Foo();
void FooConst() const;
Widget* GetPtr() { return this; }
const Widget* GetConstPtr() const { return this; }
};
而是回到使用这些代替直接使用箭头运算符:
void WidgetManager::ManagerFoo()
{
// shouldn't use "->" directly (lint?)
_pW->GetPtr()->Foo();
_pW->GetPtr()->FooConst();
//_pW->GetConstPtr()->Foo(); // this won't compile (good)
_pW->GetConstPtr()->FooConst();
}
void WidgetManager::ManagerFooConst() const
{
// shouldn't use "->" directly (lint?)
_pW->GetPtr()->Foo(); // shouldn't be used (lint?)
_pW->GetPtr()->FooConst(); // shouldn't be used (lint?)
//_pW->GetConstPtr()->Foo(); // this won't compile (good)
_pW->GetConstPtr()->FooConst();
}
但是这样做太丑陋了,编译器肯定无法执行。
具体来说,尝试为
Widget*
和const Widget*
重载operator->
似乎没有改变任何东西:ManagerFooConst()
仍然能够调用_pW->Foo()
。有没有一种方法可以实现这个目的?