C++ 类的多态一(virtual关键字--构造函数深刻理解)
//virtual关键字--构造函数深刻理解
#include<iostream>
using namespace std; /*
C语言编译器,c++编译器全部是静态链编,就是一段一段代码的编译,不会考虑上下文
例如编译到void ProtectA(Point pin) 编译器就会认为pin就是Point类型,
而不会去联系上下文,去分析pin有没有可能是子类对象
virtual关键字会自动检测这个父类对象有没有是子类对象
*/ /*
virtual关键字的作用
假设父类中存在用virtual关键字修饰的函数A,在子类中重写了该函数
当变量是父类时,c++编译器会检测传递过来的变量是不是子类对象,
如果传过来的是子类对象,那么c++编译器会自动调用子类的同名函数A,
如果传过来的是父类对象,那么c++编译就无法访问子类的同名函数A,只能调用父类的函数A
*/ class Point{
public:
Point(Point &p){
cout << "我是父类,拷贝构造函数被执行了1" << endl;
this->x = p.x;
this->y = p.y;
}
Point(int a = , int b = ){
this->x = a;
this->y = b;
}
virtual void Print(){
cout << "x=" << x << endl;
}
private:
int x;
int y;
}; class PointA :public Point{
public:
void Print(){
cout << "我是子类,我重写的父类的成员函数" << endl;
}
}; //赋值兼容原则
void ProtectA(Point pin){
pin.Print();
} void ProtectC(Point &pin){
//引用是指针
pin.Print();
} void ProtectD(Point *pin){
pin->Print();
} void ProtectB(){
PointA pa;
/*
PointA pa;详解:
这句话执行了Point类的Point(int a = 1, int b = 1)构造函数,
此时子类对象pa中的父类成员x=1,y=1,虽然x,y无法在子类pa中访问
*/
ProtectA(pa);
//调用void ProtectA(Point pin)函数,
//①执行父类拷贝构造函数 注意此时pa中的父类成员x,y都是有值的,也因此x=1,而不是乱码
//②产生新的父类临时对象pin(此时pin已经是父类对象,他执行的是拷贝构造函数)
//③父类对象调用virtual关键字修饰的函数,
//c++编译会在父类内存区域向后搜索子类属性,发现没有子类属性
//c++编译器判断这个对象时父类对象,直接调用父类的Print() ProtectC(pa);
ProtectD(&pa); } void main(){
ProtectB();
system("pause");
}
C++ 类的多态一(virtual关键字--构造函数深刻理解)的更多相关文章
- Abstract和Virtual和interface , 派生类中重写 override / new关键字
http://www.cnblogs.com/blsong/archive/2010/08/12/1798064.html C#中Abstract和Virtual 在C#的学习中,容易混淆virtua ...
- C++ 学习笔记 (七)继承与多态 virtual关键字的使用场景
在上一篇 C++ 学习笔记 (六) 继承- 子类与父类有同名函数,变量 中说了当父类子类有同名函数时在外部调用时如果不加父类名则会默认调用子类的函数.C++有函数重写的功能需要添加virtual关键字 ...
- C++ 多态、虚函数(virtual 关键字)、静态联编、动态联编
函数重写:(在子类中重写父类中的函数) 父类中被重写的函数 依然会继承 给子类. 子类中重写的函数将覆盖父类中的函数. 通过作用域分辨符 :: 可以访问到父类中的函数. 例如: #includ ...
- 条款7:为多态基类析构函数声明为virtual
基类指针指向子类对象. 子类对象必须位于堆.因此为了避免泄漏内存资源,当指针不使用时,delete掉每一个对象非常重要.但是如果基类的析构函数不声明为virtual.那么指向子类对象的指针delete ...
- C++ 类的多态三(多态的原理--虚函数指针--子类虚函数指针初始化)
//多态的原理--虚函数指针--子类虚函数指针初始化 #include<iostream> using namespace std; /* 多态的实现原理(有自己猜想部分) 基础知识: 类 ...
- 浅析C#中new、override、virtual关键字的区别
Virtual : virtual 关键字用于修饰方法.属性.索引器或事件声明,并使它们可以在派生类中被重写. 默认情况下,方法是非虚拟的.不能重写非虚方法. virtual 修饰符不能与 stati ...
- 浅析c++中virtual关键字
http://blog.csdn.net/djh512/article/details/8973606 1.virtual关键字主要是什么作用? c++中的函数调用默认不适用动态绑定.要触发动态绑定, ...
- C++ 类的多态二(函数重载--函数重写--函数重定义)
//函数重载--函数重写--函数重定义 #include<iostream> using namespace std; /* 函数重载: 必须在一个类中进行(子类无法重载父类中的函数) 子 ...
- .NET Core CSharp初级篇 1-6 类的多态与继承
.NET Core CSharp初级篇 1-6 本节内容为类的多态与继承 简介 终于讲到了面向对象三大特性中的两大特性--继承与多态.通过继承与多态,我们能很好的将类的拓展性发挥到了极致.在下面的内容 ...
随机推荐
- Linux环境搭建:2. 安装Ubuntu虚拟机
我家淘宝店,主要协助同学做毕业设计:https://shop104550034.taobao.com/?spm=2013.1.1000126.d21.pPCzDZ 1. 创建虚拟机 1. 打开VMwa ...
- 通过web php 执行shell脚本,获取的结果与直接在命令行下获取的结果不同。
公司项目中的一项小功能,统计设备的连接数.其中用到shell脚本来获取已连接设备的统计.使用命令 /bin/netstat -an| grep ESTABLISHED | awk '{print $4 ...
- C#秘密武器之表达式树
一.表达式树入门 Lambda表达式树很复杂,从概念上很难理解清楚,一句话,表达式树是一种数据结构!这里我们通过下面的这个例子来理解一下表达式树,你就能看个大概: lambda表达式树动态创建方法 s ...
- java提高篇-----理解java的三大特性之封装
在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...
- Bitmap和Drawable的互相转换
刚好之前的项目实用到.怕遗忘了.就先记录下来.然后会用到的时候直接来这copy使用就好了. 1.Bitmap ---->Drawable: public static Drawable bitm ...
- ES6 WeakMap Map 区别
WeakMap与Map的区别 1.WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名. 2.WeakMap的键名所指向的对象,不计入垃圾回收机制. 示例: const wm ...
- JS 错误处理与调试
在程序开发中难免会遇到一些错误,在成千上万的代码中去寻找错误非常明显相当于大海捞针.为此,每种计算机编程语言都要它独特的一套错误处理与调试机制.当然,JavaScript也不例外. 错误发生: 运行代 ...
- margin外边距问题
1 .上下边距会叠加 !DOCTYPE html> <html> <head> <m<etacharset="UTF-8"> < ...
- 如何从官网下载Spring
1.Spring下载地址http://repo.spring.io/release/org/springframework/spring/ 里面有各自版本下载: 方法二: 1.在百度中输入Spring ...
- 如何取得jvm实例的cpu占用(转)
时间 2014-08-29 17:11:34 田加国的博客 原文 http://www.tianjiaguo.com/programming-language/java-language/如何取得j ...