gpt4 book ai didi

c++ - 定期使用 const_cast 作为设计工具是否可以接受?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:36:20 24 4
gpt4 key购买 nike

我查看了下面的代码类型,虽然我对问题 (*) 有个人答案,但我希望得到 C++/设计专家的评论。

出于某种原因,Data 是一个具有不可修改标识符和可修改值的对象:

class Data
{
const Id m_id ; // <== note that m_id is a const member variable
Value m_value ;

Data(const Id & id, const Value & value) ;

Data(const Data & data) ;
Data & operator = (const Data & data) ;

// etc.
} ;

设计选择变成了语言选择,因为标识符在类级别 (**) 被声明为 const,以避免它的(意外)修改,即使是在类成员函数内部......

...但是如您所见,有一个复制赋值运算符,其实现方式为:

Data & Data::operator = (const Data & that)
{
if(this != &that)
{
const_cast<Id &>(this->m_id) = that.m_id ;
this->m_value = that->m_value ;
}

return *this ;
}

复制赋值运算符不是 const 限定的事实使此代码安全(用户只能在非 const 对象上合法调用此方法而不会引发未定义的行为)。

但是使用 const_cast 来修改一个 const 成员变量在 C++ 中是一个好的类设计选择吗?

我想强调以下几点:

  • 数据显然是一个值类型(它有一个operator =成员函数)
  • 在此模式中,一些其他函数也可能合理地需要 const_cast(例如,移动构造函数/赋值和/或交换函数),但不是很多。

请注意,这可能是一个代码审查问题,但这不是“日常”代码。这是一个通用的 C++ 类型设计问题,需要平衡语言的需求/能力和模式/惯用语的代码解释。

还要注意,mutable(如在 C++98 中)不是解决问题的方法,因为其目的是使成员变量尽可能不可修改。当然,mutable(如 C++11 后的“你不知道 constmutable”,作者 Herb Sutter)是偶数少一个解决方案。

(*) 我可以私下将我对该问题的回答转发给任何提出问题的人。

(**) 另一种解决方案是使对象成为非 const,并在接口(interface)级别使其成为 const(即不提供可以更改它的函数)

最佳答案

引自 cppreference:

Even though const_cast may remove constness or volatility from any pointer or reference, using the resulting pointer or reference to write to an object that was declared const or to access an object that was declared volatile invokes undefined behavior.

这意味着您的复制分配不安全,而且明显不正确。如果您声明了某些内容 const,您将永远无法安全地更改它。这与设计无关。

const_cast 的唯一有效用途是从 const 引用或指向非 const 对象(或指向 const 对象,然后不修改它)的指针中移除常量性,但这样你就不能 const_cast 代替)。

关于c++ - 定期使用 const_cast 作为设计工具是否可以接受?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25231828/

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