Const 铸造空基地 class
Const casting empty base class
const_cast
离开空基 class 并在其上调用非 const 方法是否是未定义的行为?例如
class EmptyBase {
public:
void bar() { ... }
};
class Something : public EmptyBase {
public:
void foo() const {
const_cast<EmptyBase&>(static_cast<const EmptyBase&>(*this)).bar();
}
};
我没能在标准(C++14 和 C++17)中找到相关信息来回答这个问题..
它本身并不是 UB。当您放弃常量并使用获得的泛左值修改最初声明为常量的对象时,您会得到未定义的行为。这是对此 ([dcl.type.cv]/4) 的标准引述:
Except that any class member declared mutable can be modified, any
attempt to modify a const object during its lifetime results in
undefined behavior.
仅仅调用成员函数并不是对对象的修改。这完全取决于函数 的作用 。所以如果它做了一些疯狂的事情,比如:
std::memset(this, 0, sizeof(*this));
这肯定会导致未定义的行为。但假设它没有,并且由于没有成员 可以以格式错误的方式进行修改,因此调用中没有 UB。
另一个问题,即它是否是一个好主意,有一个明显的答案。常量转换不应该乱码代码库。但是,如果基础 class 表现良好,尽管定义不明确,但如果您不能更改 class.
,则可能是可以接受的
const_cast
离开空基 class 并在其上调用非 const 方法是否是未定义的行为?例如
class EmptyBase {
public:
void bar() { ... }
};
class Something : public EmptyBase {
public:
void foo() const {
const_cast<EmptyBase&>(static_cast<const EmptyBase&>(*this)).bar();
}
};
我没能在标准(C++14 和 C++17)中找到相关信息来回答这个问题..
它本身并不是 UB。当您放弃常量并使用获得的泛左值修改最初声明为常量的对象时,您会得到未定义的行为。这是对此 ([dcl.type.cv]/4) 的标准引述:
Except that any class member declared mutable can be modified, any attempt to modify a const object during its lifetime results in undefined behavior.
仅仅调用成员函数并不是对对象的修改。这完全取决于函数 的作用 。所以如果它做了一些疯狂的事情,比如:
std::memset(this, 0, sizeof(*this));
这肯定会导致未定义的行为。但假设它没有,并且由于没有成员 可以以格式错误的方式进行修改,因此调用中没有 UB。
另一个问题,即它是否是一个好主意,有一个明显的答案。常量转换不应该乱码代码库。但是,如果基础 class 表现良好,尽管定义不明确,但如果您不能更改 class.
,则可能是可以接受的