【初级】C++中子类对象转型为父类对象时,编译器默默做了什么?
2013-09-06 15:51
246 查看
被问及C++中将子类对象转型为父类对象时,会发生什么?大部分人可能会回答说:子类成份会被"阉割",也就是说它不再具有子类特性。确实是这样,不过我想知道编译器是怎么处理“阉割”的。请看如下代码,
很明显,b0和b1都是通过调用Base的拷贝构造函数来完成构建的。对于b2,编译器首先调用Base的默认构造函数进行构造,然后调用Base的赋值运算符来把子类中的父类成份赋值给b2。
再来看看下面的代码:
很明显,main()函数中的第一个打印语句会输出1,为什么第二,三个也输出1,不是对i作加1操作了吗。原来上面的static_cast<Base>(chd).Inc()或者 ((Base)chd).Inc()会被编译器转化为如下代码:
是的,编译器通过拷贝构造函数构造出一个临时的Base对象,然后对那个临时对象进行加1操作,所以并没有改变chd对象的状态。
总结:编译器“阉割”子类对象是通过拷贝构造函数或赋值运算符来完成的。注意转型中临时对象可能产生。
Child chd; Base b0(chd); Base b1 = chd; Base b2; b2 = chd;
很明显,b0和b1都是通过调用Base的拷贝构造函数来完成构建的。对于b2,编译器首先调用Base的默认构造函数进行构造,然后调用Base的赋值运算符来把子类中的父类成份赋值给b2。
再来看看下面的代码:
class Base { public: Base() { i = 0; printf("Base()\n"); } Base(const Base & base) : i(base.i) { printf("Base copy.\n"); } Base& operator=(const Base &base) { printf("Assignment.\n"); return *this; } void Inc() {++i;} void print() {printf("%d\n",i);} int i; }; class Child : public Base { }; int main() { Child chd; chd.Inc(); // add 1 Base base(chd); // copy base.print(); static_cast<Base>(chd).Inc(); chd.print(); // 打印出1 ((Base)chd).Inc(); chd.print(); // 打印出1 return 0; }
很明显,main()函数中的第一个打印语句会输出1,为什么第二,三个也输出1,不是对i作加1操作了吗。原来上面的static_cast<Base>(chd).Inc()或者 ((Base)chd).Inc()会被编译器转化为如下代码:
Base temp(chd); temp.Inc();
是的,编译器通过拷贝构造函数构造出一个临时的Base对象,然后对那个临时对象进行加1操作,所以并没有改变chd对象的状态。
总结:编译器“阉割”子类对象是通过拷贝构造函数或赋值运算符来完成的。注意转型中临时对象可能产生。
相关文章推荐
- JAVA父类引用指向子类的对象是什么意思?有什么作用?
- C++ 子类对象当父类对象使用
- C++ 子类对象当父类对象使用
- C++子类在成员函数中不要转型为父类
- C++关于父类指针指向子类对象的问题
- C++学习基础十一——子类对象向父类对象的转化
- 父类转子类,c++对象布局
- c++中 子类对象与父类对象的内存关系
- 理解c++对象模型,子类与父类关系
- c++父类指针指向子类对象
- 对象的转型(在父类与子类之间)
- C++父类指针指向子类对象的实现原理
- C++在父类和子类之间进行转型时脑抽做了个试验
- C++ 类的继承,子类以及之类的对象 对父类成员函数的访问权限
- C++ 父类指针指向子类对象||子类指针指向父类对象的理解
- 关于父类引用指向子类对象(A a = New B();)的使用,理解向上转型
- java对象转型(casting)-父类引用指向子类对象注意点
- c++子类指针,父类指针,对象的关系
- C++虚函数表解析(图文并茂,非常清楚)( 任何妄图使用父类指针想调用子类中的未覆盖父类的成员函数的行为都会被编译器视为非法)good
- C++反汇编第四讲,反汇编中识别继承关系,父类,子类,成员对象