为什么我可以修改这个字符串值?
I0st const 方法,但工作是
对我来说不合理
#include <iostream>
#include <string>
class Foo : private std::string
{
public:
Foo(const char* c) :std::string(c) {}
const std::string& name() const
{
(std::string&)(*this) = "Change";
return (const std::string&)(*this);
}
};
int main()
{
Foo temp("value1");
std::cout << temp.name();
}
这将输出
Change
最佳答案
C 风格的显式转换,如 (std::string&)(*this)
几乎可以将任何东西转换到其他所有东西上,而不管你是否被允许使用结果。显式转换通常也被编译器解释为告诉它“我知道我在做什么。”,所以如果你滥用显式转换,不会有任何警告。
特别是 C 风格的显式转换首先尝试做
const_cast<std::string&>(*this);
这是不可能的,因为
const_cast
只能添加或删除 const
和 volatile
限定符,但不能改变类型,否则。然后它尝试
static_cast<std::string&>(*this);
这是不可能的,因为
static_cast
无法删除 const
资格,但 *this
是 const
-在功能上合格。然后它尝试
static_cast
后跟 const_cast
,例如相当于const_cast<std::string&>(static_cast<const std::string&>(*this));
这成功了,因为
*this
源自 std::string
并且可以绑定(bind)到 const std::string&
引用。 const_cast
然后删除 const
限定符。结果将是对
std::string
的引用。基类子对象。原则上,您可以像在代码中那样使用此引用并分配给它。但是,如果
this
的完整对象本身指的是声明为const
,例如如果在 main
你有const Foo temp("value1");
相反,您的代码仍然会在没有警告的情况下编译,但它会有未定义的行为,因为修改
const
对象是未定义的行为,即使您能够获得非 const
引用或指向它的指针。这就是为什么使用
const_cast
在大多数情况下是不好的风格,如果使用它,需要特别小心,它所指的对象永远不能被声明const
.你没有在你的代码中那么小心。C 风格的显式转换可以(除了许多其他危险的转换)执行
const_cast
并且应该出于同样的原因(和其他原因)不被使用。你真正想要的是
static_cast
只会在类层次结构中转换引用和指针,不会违反 const
-正确性:static_cast<std::string&>(*this) = "Change";
如果成员函数是
const
,这将为您提供相应的错误消息。 -qualified 并且将在没有未定义行为的情况下工作。或者,只要您不覆盖
operator=
派生类重载,可以调用基类operator=
也只是没有类型转换。如果成员函数是 const
,这也会给出适当的错误。 -qualified 并且将在没有未定义行为的情况下工作,否则:*this = "Change";
关于c++ - 修改 value const 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59534177/