c++ - 为什么 C 样式转换允许您转换为私有(private)基类?

标签 c++ class casting upcasting

<分区>

假设我们有这段代码

class A {
public:
    A() : x(1) {}
    virtual ~A() {}

    int x;
};

class B {
public:
    B() : y(2) {}
    virtual ~B() {}

    void g()
    {
        cout << "B::" << y << endl;
    }

    int y;
};

class C : private A, private B {
public:
    void f()
    {
        B* p = static_cast<B*>( this );
        p->g();
    }
};

int main()
{
    C c;
    ((B*)&c)->g();

    return 0;
}

main 函数中的 C 风格转换无法用 C++ 转换(static_castdynamic_castreinterpret_cast)正确表达。但是,首先允许这样做的原因是什么?不影响封装吗?

更新 这不是链接问题的重复,因为这个问题是关于 C++ 中的设计决策。它不问我能用语言做什么或不能做什么,而是问为什么做出某些决定。

最佳答案

当在指向基类和派生类的指针之间使用 C 样式指针转换时,它的行为类似于 static_cast - 即使基类是私有(private)的。

(不相关指针类型之间的 C 风格转换是 reinterpret_cast)。

标准说:

The conversions performed by

— a const_cast (5.2.11),

— a static_cast (5.2.9),

— a static_cast followed by a const_cast,

— a reinterpret_cast (5.2.10), or

— a reinterpret_cast followed by a const_cast,

can be performed using the cast notation of explicit type conversion. The same semantic restrictions and behaviors apply, with the exception that in performing a static_cast in the following situations the conversion is valid even if the base class is inaccessible:

— a pointer to an object of derived class type or an lvalue or rvalue of derived class type may be explicitly converted to a pointer or reference to an unambiguous base class type, respectively;

— a pointer to member of derived class type may be explicitly converted to a pointer to member of an unambiguous non-virtual base class type;

— a pointer to an object of an unambiguous non-virtual base class type, a glvalue of an unambiguous non-virtual base class type, or a pointer to member of an unambiguous non-virtual base class type may be explicitly converted to a pointer, a reference, or a pointer to member of a derived class type, respectively.

你的情况在第一点中有描述,所以通过static_cast进行转换,调整指针。

关于c++ - 为什么 C 样式转换允许您转换为私有(private)基类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18738538/

相关文章:

将 32 位指针转换为 64 位指针? (导致 copy_from_user 失败)

javascript - 使用 ob_get_clean 设置的 php 变量是一个字符串,但不会转换为整数

java - 使用新方法访问 ArrayList 时出现编译时错误

c# - 动态转换问题

c++ - int 的构造函数中参数的可变数量

c++ - 在新的 Visual Studio 项目中包含任何 Eigen 3.3.1 文件都不会编译

c++ - 在 AngelScript 中注册一个 C++ 类并传递一个类实例

class - 如何在 UML 图中描述 Either/Or 继承?

c++ - 接受 lambda 函数和函数指针作为参数

c++ - 为什么不能使用结构化绑定(bind)分解 lambda 表达式的捕获列表