加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – const_cast类构造函数中的const成员

发布时间:2020-12-16 09:44:13 所属栏目:百科 来源:网络整理
导读:当我希望类的成员变量在类的生命期间保持不变时,我有时会使用const_cast,但它在构造函数中需要是可变的.例: struct qqq { const vectorfoo my_foo; qqq(vectorfoo* other) { vectorfoo mutable_foo = const_castvectorfoo(my_foo) other-swap(mutable_foo);
当我希望类的成员变量在类的生命期间保持不变时,我有时会使用const_cast,但它在构造函数中需要是可变的.例:

struct qqq {
 const vector<foo> my_foo;

  qqq(vector<foo>* other) {
    vector<foo>& mutable_foo = const_cast<vector<foo>&>(my_foo)
    other->swap(mutable_foo);
  }
};

我曾经假设在构造函数中执行此操作基本上没问题,因为此时没有其他人依赖它,因此它不会与优化等交互不良.

然而,最近有人告诉我这是“未定义的行为”,并且在任何情况下构造const对象之后改变const对象基本上是非法的.

有人可以澄清吗?这是一个不好/未定义的行为/事情吗?

解决方法

这是未定义的行为.根据C 11标准的第7.1.6.1/4段:

Except that any class member declared mutable (7.1.1) can be modified,any attempt to modify a const
object during its lifetime (3.8) results in undefined behavior.

在这种情况下,您似乎希望您的对象在构造后“变得”不变.这是不可能的.

如果你的向量是const,你应该在构造函数的initialization list中初始化它:

qqq(vector<foo>& other) 
    : my_foo(std::move(other)) 
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
}

请注意,除非你有充分的理由通过指针传递 – 在这种情况下,你还应该检查指针是否为非空 – 你应该考虑通过引用传递(如上所示),这是常见的做法.

更新:

正如Pete Becker在评论中正确指出的那样,正确的设计会表明从vector参数移动的决定应该属于qqq构造函数的调用者,而不是构造函数本身.

如果构造函数总是应该从它的参数移开,那么你可以让它接受一个右值引用,清楚地表明构造函数本身对调用者的期望是什么:

qqq(vector<foo>&& other) 
//             ^^
    : my_foo(std::move(other)) 
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
}

这样,调用者必须在qqq的构造函数的输入中提供rvalue:

std::vector<foo> v;
// ...
qqq q1(v); // ERROR!
qqq q2(std::move(v)); // OK! Now the client is aware that v must be moved from

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读