【问题标题】:assign non-static const member in class with const_cast使用 const_cast 在类中分配非静态 const 成员
【发布时间】:2020-07-04 04:09:45
【问题描述】:

为什么可以使用 const_cast 分配非静态 const 成员,这在什么时候有用?

在下面的代码中,A 类和 B 类都可以编译并正常工作。但是,对于 B,它的 const 成员 s 不是使用构造函数中的初始化列表来初始化的,而是通过使用 const_cast 删除 const 并通过引用传递一个值。也可以写成 (string&)s = _s;

我不经常在作业的左侧看到 const_cast,但这个似乎工作正常。 B的构造函数的优缺点是什么?

#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;

class A {
public:
    A(const string& _s) : s(_s) {}
    void display() {cout << s << endl;}
private:
    const string s;
};

class B {
public:
    B(const string& _s) {
        const_cast<string&>(s) = _s;
    }
    void display() {cout << s << endl;}
private:
    const string s;
};

int main() {
    A a("abc");
    a.display();
    B b("def");
    b.display();
    return EXIT_SUCCESS;
}

输出:

abc
def

【问题讨论】:

  • B::B 的“缺点”是有一个不必要的const_cast。它的“优点”列表中没有任何内容。
  • 使用const_cast 分配给const 对象是UB。
  • 为什么(坏事)可以用 C++ 来完成? 因为 C++ 不是一门保姆语言,它为你提供了足够的绳索来击中自己的脚。当程序员使用强制转换时,他们是在告诉编译器“相信我,我知道我在做什么”,即使他们不知道自己在做什么,编译器也会信任他们。
  • 只有在您确定 const 引用所引用的对象未声明为 const 时才使用 const_cast。否则,在尝试修改 const 对象时,迟早会导致未定义的行为。即使在这些情况下,通常也有不需要演员表的替代方案。

标签: c++ constructor constants const-cast


【解决方案1】:

为什么可以使用 const_cast 分配非静态 const 成员,这在什么时候有用?

取决于你所说的“可以”。

程序是格式良好的,因为您修改了一个非常量左值。

程序的行为未定义,因为您修改了一个 const 对象。

这在什么时候有用?

修改 const 对象永远不会有用。

从引用中去掉 const 有时虽然很少,但很有用,这就是 const_cast 存在的原因。但它仅在您有对非 const 对象的 const 引用时才有用。

B 的构造函数有什么优点...?

无。

B的构造函数有什么...缺点?

如果调用 B 的构造函数,程序的行为是不确定的。

【讨论】:

  • 谢谢。如果我写的是(string&amp;) s = _s; 而不是const_cast&lt;string&amp;&gt;(s) = _s;,答案是否也成立?我相信第二个变体实际上已被编译器转换为第一个。
  • 是的。那是等价的。在所有情况下都避免使用后者。只能用 const cast 抛弃 constness。
猜你喜欢
  • 2011-10-22
  • 1970-01-01
  • 1970-01-01
  • 2012-07-21
  • 1970-01-01
  • 1970-01-01
  • 2013-04-11
  • 1970-01-01
  • 2016-05-20
相关资源
最近更新 更多