Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

继承关系中的类型转换相关 #44

Open
BBQGOD opened this issue Apr 19, 2021 · 0 comments
Open

继承关系中的类型转换相关 #44

BBQGOD opened this issue Apr 19, 2021 · 0 comments

Comments

@BBQGOD
Copy link

BBQGOD commented Apr 19, 2021

继承关系中的类型转换相关

派生类的向上类型转换

在课上,老师给出的课堂习题中有一个选项:

通过对象的向上类型转换,我们可以访问到因为private继承而访问不到的基类成员变量。

这一说法是错误的,一种易于理解的说法是:private继承不希望用户通过派生类对象以任何方式访问到基类的成员。
那么我们会提出疑问,各种继承方式下的向上类型转换的机制是怎样的,可以参考以下例程:

class A {};
class B: A {}; // 不阻止任何B类的用户向A进行类型转换
class C: protected A {}; // 阻止C类的对象用户向A进行类型转换
class D: private A {}; // 阻止D类的一切用户向A进行类型转换
class E: B { void test { static_cast<A *>(this); } }; // B类的继承类用户可以向A进行类型转换
class F: C { void test { static_cast<A *>(this); } }; // C类的继承类用户可以向A进行类型转换
class E: D { void test { static_cast<A *>(this); } }; // Error!D类的继承类用户不可以向A进行类型转换
int main
{
    static_cast<A *>(new B); // B类的实例用户可以向A进行类型转换
    static_cast<A *>(new C); // Error!C类的对象用户不可以向A进行类型转换
    static_cast<A *>(new D); // Error!D类的对象用户不可以向A进行类型转换
}

因此,我们可以得出结论:

  • public继承:不阻止类的任何用户进行向上类型转换
  • protected继承:阻止类的对象用户进行向上类型转换
  • private继承:阻止类的一切用户进行向上类型转换

通过类的不同用户访问权限的角度,我们可以理解不同继承方式下,派生类的向上类型转换不同的原因。

基类的向下类型转换

在课上我们学习到,基类对象不能直接进行向下类型转换。而指针和引用是可以进行向下类型转换的。下面介绍一种方法——dynamic_cast
具体语法:

dynamic_cast< type* >(e)

type必须是一个类类型且e必须是一个有效的指针,或

dynamic_cast< type& >(e)

type必须是一个类类型且e必须是一个左值,或

dynamic_cast< type&& >(e)

type必须是一个类类型且e必须是一个右值。

e的类型必须符合以下三个条件中的任何一个:
1、e的类型是目标类型type的公有派生类
2、e的类型是目标type的基类
3、e的类型就是目标type的类型

否则,dynamic_cast<type*>(e)为0,而dynamic_cast<type&>(e)dynamic_cast<type&&>(e)会抛出std::bad_cast异常。
这种方式比起强制类型转换的优点是会检查转换类型是否合法,并有良定义的处理,但会耗费大量时间。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant