【问题标题】:conditions for type casting in C++ [duplicate]C ++中类型转换的条件[重复]
【发布时间】:2019-01-19 22:42:38
【问题描述】:

我在复习继承时,看到了基于以下代码的casting的三个规则。 (来自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*

我很困惑如何理解这三个规则。 投射是否有一般条件? 成员朋友孩子是指这里吗?

我的问题主要是关于铸造而不是继承。

【问题讨论】:

  • @UKMonkey,你提到的帖子是关于继承的,但我是在询问演员阵容。
  • 阅读你的规则;阅读问题的答案;你会发现它们是一样的。
  • @UKMonkey,我不知道铸造的一般条件是什么。
  • 如果你知道怎么做,你可以投。私有基地基本上对其他人是不可见的,因此不会知道D_privB 之间的关系。而且你不能在不相关的类型之间进行转换。
  • @apple apple,这就是我想问的。非常感谢~但是根据规则2,D_priv的成员和朋友可以将D_priv*投给B*。这和你说的矛盾吗?

标签: c++ inheritance casting


【解决方案1】:

为了能够从一个类转换为父类,父类的公共成员必须可用。更准确地说,当在子类上将父类的公共成员调用给正在转换它的任何人时,它们必须是可调用的。

你可以问自己这个问题:如果我创建一个B 类型的对象,我可以调用D_prot 的公共方法吗?如果答案是肯定的,那么你可以投射它,例如:

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

更详尽的版本如下所示:

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

PS.在链接中我已经注释了不编译的行,请随意分叉代码并取消注释以查看编译器告诉的内容

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-17
    • 1970-01-01
    • 2013-02-13
    • 2017-02-11
    • 2012-05-10
    • 1970-01-01
    • 2012-09-25
    相关资源
    最近更新 更多