关于继承:C++中类型转换的条件

conditions for type casting in C++

本问题已经有最佳答案,请猛点这里访问。

我正在检查继承,我看到了基于以下代码的三个强制转换规则。(来自https://www.youtube.com/watch?V= EYUPBBKGJTCQ)

1
2
3
4
class B{};
class D_priv: private B{};
class D_prot: protected B{};
class D_pub: public B{};

三条规则:

  • 任何人都可以将D_pub*投射到B*上。D_pubB的一种特殊类型。
  • D_priv的成员和朋友可以向B*投一个D_priv*
  • D_prot的成员、朋友和孩子可以向B*投一个D_prot*
  • 我对如何理解这三条规则感到困惑。有铸造的一般条件吗?成员、朋友和孩子是指这里吗?

    我的问题主要是演员而不是遗产。


    为了能够从类强制转换为父类,父类的公共成员必须可用。更确切地说,当在子类上调用父类的公共成员时,必须能够调用父类的公共成员,无论是谁在强制转换它。

    你可以问自己这个问题:如果我创建一个B类型的对象,我可以调用D_prot的公共方法吗?如果答案是"是",则可以将其强制转换,例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class A
    {
    public:
        void foo();
    };
    class B : public A
    {
    };
    // Then when someone has a B object:
    B b;
    b.foo(); // Are we allowed to call foo()?
    static_cast<A>(b).foo(); // If yes, we can cast it as well

    更详尽的版本如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    class Base
    {
    public:
        void foo() {} // Dummy method to clarify the example
    };

    class PublicChild : public Base
    {
    public:
        void test()
        {
            foo(); // OK, we have access to Base public members
            static_cast<Base*>(this)->foo(); // OK
        }
        friend class PublicFriend;
    };

    class PublicFriend
    {
        void test(PublicChild* p)
        {
            p->foo(); // OK, the method is public anyway
            static_cast<Base*>(p)->foo(); // OK
        }
    };

    class ProtectedChild : protected Base
    {
    public:
        void test()
        {
            foo(); // OK, we have access to Base public members
            static_cast<Base*>(this)->foo(); // OK
        }
        friend class ProtectedFriend;
    };

    class ProtectedFriend
    {
        void test(ProtectedChild* p)
        {
            p->foo(); // OK, because we are a friend of ProtectedChild, we have the same visibility as ProtectedChild itself
            static_cast<Base*>(p)->foo(); // OK
        }
    };

    class PrivateChild : private Base
    {
    public:
        void test()
        {
            foo(); // OK, we have access to Base public members
            static_cast<Base*>(this)->foo(); // OK
        }
        friend class PrivateFriend;
    };

    class PrivateFriend
    {
        void test(PrivateChild* p)
        {
            p->foo(); // OK, because we are a friend of PrivateChild, we have the same visibility as PrivateChild itself
            static_cast<Base*>(p)->foo(); // OK
        }
    };

    int main()
    {
        Base b;
        b.foo(); // OK: public method

        PublicChild p1;
        p1.foo(); // OK: public inheritance makes Base::foo public
        static_cast<Base>(p1).foo(); // OK

        ProtectedChild p2;
        p2.foo(); // error: protected inheritance makes Base::foo protected
        static_cast<Base>(p2).foo(); // error

        PrivateChild p3;
        p3.foo(); // error: private inheritance makes Base::foo private
        static_cast<Base>(p3).foo(); // error
    }

    示例:https://ideone.com/zbaqbu

    在链接中,我对未编译的行进行了注释,可以自由地派生代码并取消对它们的注释,以查看编译器的提示。