在C++中进行类型转换的条件

23 浏览
0 Comments

在C++中进行类型转换的条件

这个问题已经有了答案

C++中公有、私有和保护继承的区别是什么?

我正在复习继承,看到以下代码基于转换的三个规则。 (来自https://www.youtube.com/watch?v=EYuPBkgJtCQ)

class B{};
class D_priv: private B{};
class D_prot: protected B{};
class D_pub: public B{};

三个规则:

  1. 任何人都可以将D_pub*转换为B*D_pub是一种特殊的B
  2. D_priv的成员和朋友可以将D_priv*转换为B*
  3. D_prot的成员、朋友和孩子可以将D_prot*转换为B*

我非常困惑如何理解这三个规则。是否有一个通用条件可以用于转换?这里的成员朋友孩子是什么意思?

我的问题主要是关于转换而不是继承。

admin 更改状态以发布 2023年5月24日
0
0 Comments

为了能够将一个类从子类转换为父类,父类的公共成员必须可用。更准确地说,当在子类上调用它们并将其转换给任何人时,必须能够调用父类的公共成员。\n\n您可以问自己这个问题:如果我创建一个类型为 B 的对象,我能够调用 D_prot 的公共方法吗?如果答案是肯定的,那么您可以将其进行类型转换,例如:\n\n

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(b).foo(); // If yes, we can cast it as well

\n\n更详细的版本如下:\n\n

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(this)->foo(); // OK
    }
    friend class PublicFriend;
};
class PublicFriend
{
    void test(PublicChild* p)
    {
        p->foo(); // OK, the method is public anyway
        static_cast(p)->foo(); // OK
    }
};
class ProtectedChild : protected Base
{
public:
    void test()
    {
        foo(); // OK, we have access to Base public members
        static_cast(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(p)->foo(); // OK
    }
};
class PrivateChild : private Base
{
public:
    void test()
    {
        foo(); // OK, we have access to Base public members
        static_cast(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(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(p1).foo(); // OK
    ProtectedChild p2;
    p2.foo(); // error: protected inheritance makes Base::foo protected
    static_cast(p2).foo(); // error
    PrivateChild p3;
    p3.foo(); // error: private inheritance makes Base::foo private
    static_cast(p3).foo(); // error
}

\n\n示例:https://ideone.com/Zbaqbu\n\nPS.在链接中,我已经注释了不编译的行,随意派生代码并取消注释以查看编译器的反馈。

0