const构建空基类

Cur*_*ous 6 c++ const-cast language-lawyer c++14 c++17

它是未定义的行为来const_cast消除一个空的基类并在其上调用非const方法吗?例如

class EmptyBase {
public:
    void bar() { ... }
};

class Something : public EmptyBase {
public:
    void foo() const {
        const_cast<EmptyBase&>(static_cast<const EmptyBase&>(*this)).bar();
   }
};
Run Code Online (Sandbox Code Playgroud)

我无法在标准(C++ 14和C++ 17)中找到解决这个问题的相关信息.

Sto*_*ica 8

它不是UB本身.当你抛弃constness并使用获得的glvalue来修改最初声明为const的对象时,你会得到未定义的行为.这是关于此的标准报价([dcl.type.cv]/4):

除了可以修改任何声明为mutable的类成员之外,任何在其生命周期内修改const对象的尝试都会导致未定义的行为.

仅仅调用成员函数不是对象的修改.这一切都取决于功能的作用.所以,如果它做了像疯狂的事情:

std::memset(this, 0, sizeof(*this));
Run Code Online (Sandbox Code Playgroud)

那肯定会导致未定义的行为.但假设它没有,并且由于没有成员以不正确的方式进行修改,因此呼叫中没有UB.

另一个问题,无论是否是一个好主意,都有一个明显的答案.Const强制转换不应该丢弃代码库.但是如果基类表现良好,虽然没有明确定义,但如果你不能改变这个类,那也是可以接受的.

  • @ n.caillou - 对于格式良好的程序中的任何对象类型,否则`sizeof`可能不会返回0.在成员函数内部,它会将`*this`视为"完整"对象.所以`sizeof`可能会返回1.实际上,这意味着你将会对"Something"的记忆大打折扣. (2认同)