时间:2021-05-20
本文实例讲解了C++中基类和派生类之间的转换。对于深入理解C++面向对象程序设计有一定的帮助作用。此处需要注意:本文实例讲解内容的前提是派生类继承基类的方式是公有继承,关键字public。具体分析如下:
以下程序为讲解示例:
#include<iostream>using namespace std;class A{public: A(int m1, int n1):m(m1), n(n1){} void display();private: int m; int n;};void A::display(){ cout << "m = " << m << endl; cout << "n = " << n << endl;}class B :public A{public: B(int m1, int n1, int p1) :A(m1, n1), p(p1){} void display();private: int p;};void B::display(){ A::display(); cout << "p = " << p << endl;}void print1(A& a){ a.display();}void print2(B& b){ b.display();}void print3(A a){ a.display();}void print4(B b){ b.display();}int main(){ A a(3, 4);// a.display(); B b(10, 20, 30);// b.display(); A * pa; B * pb; pa = &a;// pa->display(); pb = &b;// pb->display();// pa = &b;// pa->display();// pb = &a; //错误。派生类指针不能指向基类对象。// print1(b);// print2(a); //错误。不能用基类对象给派生类引用赋值。// print3(b);// print4(a); //错误。不能用基类对象给派生类对象赋值。// pb = pa; //不能用基类指针给派生类指针赋值。 pb = (B*)pa; //可以强制转换,但是非常不安全。 pb->display(); //出现安全问题,p无法访问,因为a中没有p成员 system("pause"); return 0;}切记:派生类对象是基类对象,派生类中包含有基类的成员。基类对象不是派生类对象,它不能包含派生类型的成员。
一、派生类到基类的转化
1.派生类对象地址赋值给基类指针
main函数中执行以下代码
A a(3, 4);// a.display(); B b(10, 20, 30);// b.display(); A * pa;// B * pb;// pa = &a;// pa->display();// pb = &b;// pb->display(); pa = &b; pa->display(); //会输出 10 20pa为基类指针,指向派生类对象是合法的,因为派生类对象也是基类对象。语句会输出派生类对象中基类部分。
注意:这里并不会调用派生类的display函数,调用的是基类的display函数,因为指针pa是基类指针,编译器在编译阶段只知道pa的类型。如果要实现调用派生类的display函数,需要用到虚函数实现多态性。之后的文章会讲到。
进一步解释一下编译时和运行时的区别。
编译时编译器能知道pa的类型为A *,但是不知道它指向了哪个对象,假如有以下语句
A a(3, 4);B b(10, 20, 30);A* pa;int number;cin >> number;if (number >= 0) pa = &a;else pa = &b;pa指向的对象类型依赖于输入,运行时才输入,所以编译器是没有办法知道pa指向哪个类型的。
2.派生类对象赋值给基类引用
引用跟指针基本没有区别,引用本质上是指针,是个指针常量,具体可以参照我的另一篇C++中的引用和指针的联系和区别
main函数中执行以下代码
A a(3, 4);B b(10, 20, 30);print1(b); //会输出 10 20形参为基类引用,实参为派生类对象,派生类对象也是基类对象,可以赋值给基类引用。输出派生类中基类部分。
注意:此时对象本身并未复制,b仍然是派生类对象,前面说过了引用就是一个指针。
3.派生类对象赋值给基类对象。
A a(3, 4);B b(10, 20, 30);print3(b);派生类对象基类部分被复制给形参。
注意:实际上没有从派生类对象到基类对象的直接转换。对基类对象的赋值或初始化,实际上在调用函数,初始化时调用构造函数,赋值时调用赋值操作符。
二、基类到派生类的转化
切记:这种转换有可能引发严重的安全问题,编写代码时不要使用。没有基类到派生类的自动转换,原因在于基类对象只能是基类对象,不能包含派生类型的成员。
如果允许用基类对象给派生类对象赋值,那么就可以试图使用该派生类对象访问不存在的成员。
A a(3, 4);B b(10, 20, 30);A * pa;B * pb;// print2(a); //错误。不能用基类对象给派生类引用赋值。// print4(a); //错误。不能用基类对象给派生类对象赋值。// pb = &a; //错误。派生类指针不能指向基类对象。pa = &a;pb = &b;//pb = pa; //错误。不能用基类指针给派生类指针赋值。pb = (B*)pa; //可以强制转换,但是非常不安全。pb->display(); //出现安全问题,p无法访问,因为a中没有p成员注意到我们使用强制转换时,当派生类添加了基类中不存在的成员时,会出现安全问题。
pb->display();会调用派生类的display函数,但是它指向的内存是基类对象a的内存,p不存在。会出现严重后果。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
C++派生类的构成派生类中的成员包括从基类继承过来的成员和自己增加的成员两大部分。从基类继承的成员体现了派生类从基类继承而获得的共性,而新增加的成员体现了派生类
只有公用派生类才是基类真正的子类型,它完整地继承了基类的功能。基类与派生类对象之间有赋值兼容关系,由于派生类中包含从基类继承的成员,因此可以将派生类的值赋给基类
一、前言在上一篇C++基础博文中讨论了C++最基本的代码重用特性——类继承,派生类可以在继承基类元素的同时,添加新的成员和方法。但是没有考虑一种情况:派生类继承
C++类的多继承在前面的例子中,派生类都只有一个基类,称为单继承。除此之外,C++也支持多继承,即一个派生类可以有两个或多个基类。多继承容易让代码逻辑复杂、思路
C++基类与派生类的转换在公用继承、私有继承和保护继承中,只有公用继承能较好地保留基类的特征,它保留了除构造函数和析构函数以外的基类所有成员,基类的公用或保护成