C++ Primer 学习笔记(9): 基类和派生类的转换
2010-03-24 20:14
246 查看
1、派生类到基类的转换
如果有一个派生类型的对象,则可以使用它的地址对基类类型的指针进行赋值或初始化。同样,可以使用派生类型的引用或对象初始化积累类型的引用。严格说来,对对象没有类似转换。编译器不会自动将派生类型对象转换成基类类型对象。
1.1 引用转换不同于转换对象
将派生类型的对象传给希望接受基类引用的函数时,引用直接绑定到该对象,虽然看起来是在传递对象。转换不会改变派生类型对象,该对象仍然是派生类型对象。
当将派生类型对象传给希望接受基类类型对象的函数时,情况完全不同。这时该派生类对象的基类部分被复制到形参。
1.2 用派生类对象对基类对象进行初始化或赋值
用派生类对象对基类对象赋值有两种情况
(1) 基类显式定义了将派生类型对象赋值或复制给基类对象的函数,即构造函数或赋值运算符来实现,这时根据用户定义的动作来进行转换。
(2)未定义上述操作,则派生类的非基类成员被切掉,只将基类部分赋值给基类对象。
1.3 派生类到基类转换的可访问性
关于这个问题,在C++ primer 4 中文版上翻译的很恶心,如下:
这一段我到现在没弄明白,写了一段代码验证:
从中可以发现,假设类层次如下
base;
son:private base;
grandson: xxx son;
则在grandson中甚至都不能定义base类型的对象,自然也就不存在什么访问权限的问题了,而如果son的继承方式是son:protected base,则没有问题,但是son仍然不能传递给一个base类型的引用或指针
上面的代码稍作改动就可以通过:
2、基类到派生类的转换
基类到派生类的自动转换是不存在的,将基类对象赋值给派生类会出现错误。
如果有一个派生类型的对象,则可以使用它的地址对基类类型的指针进行赋值或初始化。同样,可以使用派生类型的引用或对象初始化积累类型的引用。严格说来,对对象没有类似转换。编译器不会自动将派生类型对象转换成基类类型对象。
1.1 引用转换不同于转换对象
将派生类型的对象传给希望接受基类引用的函数时,引用直接绑定到该对象,虽然看起来是在传递对象。转换不会改变派生类型对象,该对象仍然是派生类型对象。
当将派生类型对象传给希望接受基类类型对象的函数时,情况完全不同。这时该派生类对象的基类部分被复制到形参。
1.2 用派生类对象对基类对象进行初始化或赋值
用派生类对象对基类对象赋值有两种情况
(1) 基类显式定义了将派生类型对象赋值或复制给基类对象的函数,即构造函数或赋值运算符来实现,这时根据用户定义的动作来进行转换。
(2)未定义上述操作,则派生类的非基类成员被切掉,只将基类部分赋值给基类对象。
1.3 派生类到基类转换的可访问性
关于这个问题,在C++ primer 4 中文版上翻译的很恶心,如下:
如果是public继承,则用户代码和后代码类都可以使用派生类到基类的转换。如果类是使用private或protected继承派生的,则用户代码不能将派生类型对象转换为基类对象。如果是private继承,则从private继承类派生的类不能转换为基类。如果是protected继承,则后续派生类的成员可以转换为基类类型。 对比英文版: If the inheritance is public, then both user code and member functions of subsequently derived classes may use the derived-to-base conversion. If a class is derived using private or protected inheritance, then user code may not convert an object of derived type to a base type object. If the inheritance is private, then classes derived from the privately inherited class may not convert to the base class. If the inheritance is protected, then the members of subsequently derived classes may convert to the base type. 另外有一个Tips: To determine whether the conversion to base is accessible, consider whether a public member of the base class would be accessible. If so, the conversion is accessible; otherwise, it is not. 中文版上是: 要确定到基类的转换是否可访问,可以考虑基类的public成员是否可访问,如果可以,转换是可访问的,否则,不可访问
这一段我到现在没弄明白,写了一段代码验证:
#include"iostream" using namespace std; class c00 { public: void print() { cout<<"c00::print"<<endl; } private: int c00a; }; class c10 : public c00 { private: int c10a; public: void f(const c00 & c) //1 ok { } }; class c11 : protected c00 { private: int c11a; public: void f(const c00 & c) //5 ok { } }; class c12 : private c00 { private: int c12a; public: void f(const c00 & c) //5 ok { } }; class c21 : public c11 { private: int c21a; public: void f(const c00 & c) //4 ok { } }; class c22 : public c12 { private: int c22a; public: c00 test; //error,连定义c00对象都不可以 void f(const c00 & c) //3 error { } }; void f(const c00 & c) { } int main() { c10 t10; c21 t21; c12 t22; f(t10); //1 ok // f(t21); //2 error // f(t22); //2 error }
从中可以发现,假设类层次如下
base;
son:private base;
grandson: xxx son;
则在grandson中甚至都不能定义base类型的对象,自然也就不存在什么访问权限的问题了,而如果son的继承方式是son:protected base,则没有问题,但是son仍然不能传递给一个base类型的引用或指针
上面的代码稍作改动就可以通过:
class c22 : public c12 { private: int c22a; public: ::c00 test; //现在ok了 void f(const ::c00 & c) //ok!!! { } };
2、基类到派生类的转换
基类到派生类的自动转换是不存在的,将基类对象赋值给派生类会出现错误。
相关文章推荐
- 派生类到基类的转换(c++学习笔记)
- c++ primer 学习杂记2【派生类到基类转换的可访问性】
- 派生类到基类的转换(c++学习笔记)
- C++ Primer 学习笔记_66_面向对象编程 -定义基类跟派生类[续]
- C++ Primer 面向对象编程 15.3 基类派生类相互转换 15.4. 构造函数和复制控制
- C++ Primer 学习笔记_62_重载操作符与转换 --调用操作符和函数对象
- C++ Primer学习笔记——$14 操作符重载、函数对象及类类型转换
- 《c++ primer》 第14章 重载运算与类型转换 学习笔记
- C++ Primer 学习笔记_63_满载操作符与转换 -转换与类类型【上】
- C++ Primer 学习笔记_60_重载操作符与转换 --赋值、下标、成员訪问操作符
- C++ Primer 学习笔记:类型转换
- C++学习笔记(1)——基类、派生类的对象空间
- MFC学习笔记(三)之基类、派生类
- C++ Primer 学习笔记十四 —— 重载操作符与转换
- C++ Primer 学习笔记_63_重载运算符和转换 --转换和类类型【上】
- C++ primer 详解派生类向基类转换的可访问性
- C/C++日常学习总结(第十四篇)C++基类与派生类的转换
- C++ Primer 学习笔记_61_重载操作符与转换 --自增/自减操作符
- c++ primer(第五版)学习笔记及习题答案代码版(第十四章)重载运算与类型转换
- C++笔记:派生类到基类转换到可访问性