【一天一篇CPP】基类与派生类的转换(单向:从派生类赋值给基类,舍弃一部分)
来源:互联网 发布:打谱软件muse用法 编辑:程序博客网 时间:2024/05/19 22:51
我们知道一般的赋值兼容,如double d, int i, int *ip; d = i 可以直接赋值, i = d 可以舍弃小数赋值,而 ip = 1024 则出现错误,要添加强制转换,如 ip = (int *) 1024,则不算赋值兼容。
不同数据之间的自动转换和赋值,称为赋值兼容。
1. 那么基类对象和派生类对象是否存在赋值兼容关系?
存在,但是是单向的【从派生类赋值给基类,舍弃其它部分】,而且只能赋值数据成员【为什么?因为赋值函数成员会导致混乱】!只有公有继承才能赋值【为什么?因为私有继承和保护继承的基类成员在类的外部是不可见的,防止意外操作】!
2. 如何赋值?什么情况下系统会自动转换?
A 派生类可以向基类对象赋值,
【假如 B 继承于 A 】A a1; B b1; a1 = b1;在赋值的时候舍弃派生类自己的成员,“大材小用”。
一个例子【注意是公有继承】:
#include <iostream>#include <string>using namespace std;class A{public:A(int i) : a(i){}//构造函数void COUT() {cout << a <<endl;}private:int a;};class B : public A{public: B(int i) : A(i) {b = 10;}int b;};int main(){A a1(0);B b1(20);a1 = b1;//即使是私有成员a,也将被赋值a1.COUT();return 0;}
B 派生类可以向基类对象的引用进行赋值和初始化。【派生类的基类部分和引用具有相同地址】
#include <iostream>#include <string>using namespace std;class A{public:A(int i) : a(i){}//构造函数private:int a;};class B : public A{public: B(int i) : A(i) {b = 10;}int b;};int main(){A a1(10);B b1(20);A &r = a1;r = b1;//只是一般的赋值操作,引用是不能重定向的A &r2 = b1;//r和a1具体相同地址,b1的基类部分地址和r2具有相同地址cout << &r <<endl;cout << &a1 <<endl;cout << &b1 <<endl;cout << &r2 <<endl;cout << &b1 <<endl;return 0;}
C 如果函数的参数是基类对象或基类对象的引用,实参也可以是子对象【子对象:基类经过公有继承后的子类的对象】,赋值过程和上面的类似。
void fun(A &r) {cout << r.num <<endl; } fun( b1 )
D 派生类的对象的地址可以赋给指向基类对象的指针变量,依然是指向派生类继承于该基类的数据部分的起始地址。
3.一个有趣的实例
#include <iostream>#include <string>using namespace std;class Base{int base;};class A{public:A(int i) : a(i){}//构造函数private:int a;};class B : public Base,public A{public: B(int i) : A(i) {b = 10;}int b;};int main(){A a1(10);B b1(20);A *ap = &b1;cout << (int *)ap <<endl;cout << (int *)&b1 <<endl;return 0;}请问上面的ap和&b1值相同吗,答案是不同的。因为B类继承了两个父类,一个是Base【这个是B类对象的地址真正指向的类,因为它是第一个父类】,一个是A,而ap是指向B类对象中A类的部分的地址,所以不同。【假如是私有继承和保护继承,那么A *ap = &b1; 操作将产生错误,因为B类中继承于A类的数据在其它地方是不可见的】
4.另一个有趣的问题【假如A和B类都有display()成员函数,且B继承于A】
A *p = b1;则p->display()调用的是A的display函数还是B的display函数呢,答案是A的display()函数。
- 【一天一篇CPP】基类与派生类的转换(单向:从派生类赋值给基类,舍弃一部分)
- 基类与派生类的赋值
- 派生类的对象赋值给基类对象
- 基类与派生类的转换
- 基类与派生类的转换
- 派生类与基类的转换
- 基类与派生类的转换
- 基类与派生类的转换
- 基类与派生类的转换
- 派生类与基类的转换
- 基类与派生类的转换
- 【一天一篇CPP】派生类的构造函数和析构函数
- C++派生类与基类的赋值
- c++派生类对象赋值给基类对象
- C#控制台基础 里氏转换之子类可以赋值给父类即派生类可以赋值给基类
- 基类与派生类的转换(2)
- 基类与派生
- 基类与派生
- 字符集
- 感冒治疗方法
- Tcp协议三次握手流程_world
- Android常用的工具类
- 数据库备份脚本
- 【一天一篇CPP】基类与派生类的转换(单向:从派生类赋值给基类,舍弃一部分)
- xcode object c 函数注释
- 俞敏洪+马云+牛根生+史玉柱经典语录
- Java远程通讯可选技术及原理
- B. Physics Practical
- respond-design
- .Net调用非托管代码(P/Invoke与C++InterOP)
- jQuery遍历列表数据
- H264 码率控制