gpt4 book ai didi

c++ - 如何强制执行有关指针数据成员的常量正确性

转载 作者:太空狗 更新时间:2023-10-29 21:11:23 26 4
gpt4 key购买 nike

在工作中进行讨论后,我们似乎无法在具有指针数据成员的类上强制执行“逻辑”常量正确性,例如:

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 的非常量函数的指针成员,同时仍允许从 WidgetManager 的其他非常量函数调用它们.这意味着,将指针声明为 std::shared_ptr<const Widget> (即 const Widget* )已出局。

此外,我们想要使指针引用另一个选项 Widget在经理的生命周期内,所以我们真的不想将其作为数据成员持有(并且不能通过引用持有)。

当然,这里强制执行所有“按位”常量正确性,因为 WidgetManager 没有数据成员可以从 const 方法中修改(包括由 Widget 指向的特定 _pW),但我们希望实现“逻辑”const 正确性,即使指向的成员也无法修改。

我们唯一想出的办法是在 this 中添加常量和非常量“Widget 的 setter/getter ” :

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();
}

但这太丑陋了,编译器绝对不能强制执行。

具体来说,试图重载 operator->对于 Widget*const Widget*似乎没有任何改变:ManagerFooConst()仍然可以调用_pW->Foo() .

有什么办法可以实现吗?

最佳答案

您可以使用(或重新实现)std::experimental::propagate_const

然后您的代码将是:

class Widget {
public:
void Foo();
void FooConst() const;
};

class WidgetManager {
public:
WidgetManager() : _pW(std::make_shared<Widget>()) {}

void ManagerFoo()
{
_pW->Foo(); // OK
_pW->FooConst(); // OK
}

void ManagerFooConst() const
{
_pW->Foo(); // not compile
_pW->FooConst(); // OK
}

private:
std::experimental::propagate_const<std::shared_ptr<Widget>> _pW;
};

Demo

关于c++ - 如何强制执行有关指针数据成员的常量正确性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50764540/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com