C++学习总结 复习篇2
延续上一小节内容:下面继续讲解虚函数和多态
- 虚函数和多态
- 基类指针可以指向任何派生类的对象,但是不能调用派生类对象的成员。
- 但是,基类可以调用覆盖了虚函数的函数。(现在调用将来,这有问题,说明现在影响了将来。)
- 基类可以被继承,如果虚函数没有被实现,可以继续被下一个类继承。
- 当派生类没有能够覆盖虚函数的时候,若派生类的对象访问这个函数,那么此时将使用基类定义的函数。(现在调用过去,没有问题,已经定义过)
举例:
// BlankTest.cpp : 定义控制台应用程序的入口点。
//知识点:虚函数
//虚函数的强大之处在于能够预测未来。
//记住:基类指针可以指向任何派生类型的对象,但不能访问派生类型对象中定义的成员,但是可以调用虚函数(纯虚也可以)的实现函数。
#include "stdafx.h"
#include <iostream>
using namespace std;
class A
{
public:
virtual void f()
{
cout << "我是虚函数 " << endl;
}
protected:
private:
};
class B : public A
{
public:
void f()
{
cout << "我派生自A " << endl;
}
};
class C : public B
{
public:
void f()
{
cout << "我派生自B"<< endl;
}
};
class D :public A// 没有覆盖A中的虚函数,此时D的对象调用f这个函数的时候,将调用基类当中的函数。
{
public:
void ff()
{
cout << "没有覆盖虚函数!" << endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A *p = new A();
B b;
C c;
D d;
p->f();
p = &b;
p->f();
p = &c;
p ->f();
p = &d;
p->f(); //基类指针可以调用虚函数的实现函数。即使它是派生类对象当中的成员。
//p -> ff(); //基类指针没法调用派生类当中的成员。
d.ff();
return 0;
}
纯虚函数与抽象类
解释:含有一个或多个的纯虚函数的类叫抽象类。
特点:抽象类只能被继承不能被实例化。派生类必须覆盖这个纯虚函数,这个和虚函数有点不同,虚函数中,它的派生类不一定要必须覆盖。有时候,我们可以这样理解:
抽象类的派生类,才是我们需要的类,我们通过派生类,就可以利用基类的接口,调用基类的成员,而且可以基于派生类的不同而调用不同版本的虚函数的实现函数。
即:可以根据自己的需要,对纯虚函数重新定义,来满足自己的需要。
举例:
// BlankTest.cpp : 定义控制台应用程序的入口点。
//知识点:虚函数
//虚函数的强大之处在于能够预测未来。
//记住:基类指针可以指向任何派生类型的对象,但不能访问派生类型对象中定义的成员,但是可以调用虚函数(纯虚也可以)的实现函数。
#include "stdafx.h"
#include <iostream>
using namespace std;
class A
{
public:
virtual void f() = 0 //纯虚函数
{
cout << "我是虚函数 " << endl;
}
void aa()
{
cout << "基函数的成员函数!" << endl;
}
protected:
private:
};
class B : public A
{
public:
void f()
{
cout << "我派生自A " << endl;
}
};
class C : public B
{
public:
void f()
{
cout << "我派生自B"<< endl;
}
};
class D :public A// 没有覆盖A中的虚函数
{
public:
void ff()
{
cout << "没有覆盖虚函数!" << endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
B b;
C c;
//D d; //D没有实现纯虚函数,所以不能定义对象。
b.f();
b.aa();
c.f();
c.aa();
return 0;
}
多态:
多态分为两种: 编译时的多态与运行时的多态。
而编译时的多态一般指早期绑定;运行时的多态指动态绑定。
早期绑定:函数的重载,函数的调用以及运算符重载。简单点说,就是在编译的时候就可以确定调用某一个函数了,这个函数是确定的。
动态绑定:一般指虚函数。即:运行时才能确定函数的调用。
-
预处理器先用编译器对源代码进行处理。
主要有以下几种: #include #define #ifndef #if #else
我们可以应用预处理器提高编程的效率。
举例:
// BlankTest.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
using namespace std;
//#define DEBUG //通过这行可以决定 调试信息 的有无,这个比较好。赞一个。
int _tmain(int argc, _TCHAR* argv[])
{
#ifdef DEBUG
cout << "我在调试模式下!" << endl;
#endif // _DEBUG
cout << "我在运行模式下"<<endl;
return 0;
}
- C++运算符重载
运算符重载和函数重载有异曲同工之妙,不同之处在于运算符重载,载的是构造类型的数据,基本数据类型的数据不需要重载。重载的目的是为了让运算更加简洁、明白。
所谓的重载是对里面的运算符进行重新使用,而且只是针对这一种运算符,不是其他的。
语法格式:
返回类型 operator 单目运算符(参数列表)
{
//函数体
}
返回类型 operator 双目运算符(虚参1, 虚参2)
{
//函数体
}
注:对于双目运算符,两个虚参中至少得有一个是构造类型。
- C++命名空间
所谓命名空间,你心里面想着文件夹的概念就OK了,主要用处就是为了避免冲突。
比如,我在a文件夹下建立文件b,我也可以在c文件夹下建立文件b,但就是不能在 a 文件夹下,建立两个b。
格式:
namespace 命名空间名称
{
//函数体
}
而且,命名空间也要符合命名规范,所以对于命名空间名称我们也是可以起别名的,比如 namespace geography information system,我们可以简写为: namespace GIS = geography information system;
以上只是一种使用别名的规范而已。
Using 的作用:就是使当前文件夹下所有的函数名 暴露 在源程序中,这样我们就可以省略写 "命名空间名:: 使用到的名称或命令"。
举例:
// BlankTest.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
//using namespace std;
using std::cout;
//以下两个同名的函数:之所以不报错,是因为他们在不同的命名空间下。
//#define DEBUG //通过这行可以决定 调试信息 的有无,这个比较好。赞一个。
namespace zhu
{
void show()
{
cout << "我在zhu这个namespace下!" << std::endl;
}
}
namespace xue
{
void show()
{
cout << "我在xue这个namespace下!" << std::endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
zhu::show();
xue::show();
#ifdef DEBUG
cout << "我在调试模式下!" << endl;
#endif // _DEBUG
cout << "我在运行模式下"<< std::endl;
return 0;
}
命名空间和类联系在一起,珠联璧合,天下无敌。命名空间是类的一种有效的组织结构方式,我们用命名空间可以有效的将类进行分类管理,每个类有一个命名空间,这样我们在做大型程序开发时,可以为类库添加结构和层次的组织关系。
举例:
// BlankTest.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
//using namespace std;
using std::cout;
//以下两个同名的函数:之所以不报错,是因为他们在不同的命名空间下。
//#define DEBUG //通过这行可以决定 调试信息 的有无,这个比较好。赞一个。
namespace zhu
{
void show()
{
cout << "我在zhu这个namespace下!" << std::endl;
}
}
namespace xue
{
void show()
{
cout << "我在xue这个namespace下!" << std::endl;
}
}
namespace kui
{
class A
{
public:
void show()
{
cout << "我是属于kui命名空间里面A类里面的函数!" << std::endl;
}
};
}
namespace kui1
{
class A
{
public:
void show()
{
cout << "我是属于kui1命名空间里面A类里面的函数!" << std::endl;
}
};
}
int _tmain(int argc, _TCHAR* argv[])
{
zhu::show();
xue::show();
kui::A a;
a.show();
kui1::A b;
b.show();
#ifdef DEBUG
cout << "我在调试模式下!" << endl;
#endif // _DEBUG
cout << "我在运行模式下"<< std::endl;
return 0;
}
C++学习总结 复习篇2的更多相关文章
- C++ 学习总结 复习篇
友元的使用 分为友元类和友元函数 //友元类与友元函数的共同点:都可以让某一个类作为另一个类或者函数的参数. //友元类:它让当前类成为另一个类的友元,然后,另一个类 ...
- NOIP复习篇
NOIP复习篇---枚举 --------------------------------------------------------------------------------------- ...
- Java工程师学习指南 初级篇
Java工程师学习指南 初级篇 最近有很多小伙伴来问我,Java小白如何入门,如何安排学习路线,每一步应该怎么走比较好.原本我以为之前的几篇文章已经可以解决大家的问题了,其实不然,因为我之前写的文章都 ...
- 数据库MySQL学习笔记高级篇
数据库MySQL学习笔记高级篇 写在前面 学习链接:数据库 MySQL 视频教程全集 1. mysql的架构介绍 mysql简介 概述 高级Mysql 完整的mysql优化需要很深的功底,大公司甚至有 ...
- 一步步学习javascript基础篇(0):开篇索引
索引: 一步步学习javascript基础篇(1):基本概念 一步步学习javascript基础篇(2):作用域和作用域链 一步步学习javascript基础篇(3):Object.Function等 ...
- 一步步学习javascript基础篇(3):Object、Function等引用类型
我们在<一步步学习javascript基础篇(1):基本概念>中简单的介绍了五种基本数据类型Undefined.Null.Boolean.Number和String.今天我们主要介绍下复杂 ...
- Python3学习(3)-高级篇
Python3学习(1)-基础篇 Python3学习(2)-中级篇 Python3学习(3)-高级篇 文件读写 源文件test.txt line1 line2 line3 读取文件内容 f = ope ...
- Python3学习(2)-中级篇
Python3学习(1)-基础篇 Python3学习(2)-中级篇 Python3学习(3)-高级篇 切片:取数组.元组中的部分元素 L=['Jack','Mick','Leon','Jane','A ...
- Python3学习(1)-基础篇
Python3学习(1)-基础篇 Python3学习(2)-中级篇 Python3学习(3)-高级篇 安装(MAC) 直接运行: brew install python3 输入:python3 --v ...
随机推荐
- (转)git clone: error: RPC failed; result=18, HTTP code = 200 解决办法
git clone: error: RPC failed; result=18, HTTP code = 200 解决办法 分类: git2013-09-01 17:03 10753人阅读 评论(2) ...
- Matplotlib基础图形之散点图
Matplotlib基础图形之散点图 散点图特点: 1.散点图显示两组数据的值,每个点的坐标位置由变量的值决定 2.由一组不连续的点组成,用于观察两种变量的相关性(正相关,负相关,不相关) 3.例如: ...
- WordPress 编辑器没有可视化
第一次安装wordpress后出现文章编辑器只有一行按钮的问题,即使我安装了其他的编辑插件也是一样只有一行, 解决方法: 原来是再Users->All Users 中勾选了Disable the ...
- HDu-2896 病毒侵袭,AC自动机模板题!
病毒侵袭 模板题,不多说了.. 题意:n个不同的字符串分别代表病毒特征,给出m次查询,每次一个字符串(网址),求这个字符串中有几个病毒特征,分别从大到小输出编号,最后输出所有的带病毒网址个数.格式请看 ...
- POJ-2187 Beauty Contest,旋转卡壳求解平面最远点对!
凸包(旋转卡壳) 大概理解了凸包A了两道模板题之后在去吃饭的路上想了想什么叫旋转卡壳呢?回来无聊就搜了一下,结果发现其范围真广. 凸包: 凸包就是给定平面图上的一些点集(二维图包),然后求点集组成的 ...
- bzoj 4401 块的计数 思想+模拟+贪心
块的计数 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 455 Solved: 261[Submit][Status][Discuss] Descr ...
- EC++学习笔记(五) 实现
条款26:尽可能延后变量定义式的出现时间 尽可能延后变量的定义,知道非得使用该变量的前一刻为止方法A: Widget W; ; i < n; ++i) { W = ... } 方法B: ; i ...
- 【AIM Tech Round 5 (Div. 1 + Div. 2) 】
A:https://www.cnblogs.com/myx12345/p/9844152.html B:https://www.cnblogs.com/myx12345/p/9844205.html ...
- VirtualBox 5.0.10 中 Fedora 23 在安装了增强工具后无法自动调节虚拟机分辨率的问题(改)
VirtualBox 5.0.10 中安装 Fedora 23,即使在安装了增强工具后,仍然会发现虚拟机无法根据 VirtualBox 的运行窗口大小自动进行分辨率调节.究其原因,主要是因为 Fedo ...
- [TJOI2019]唱、跳、rap和篮球_生成函数_容斥原理_ntt
[TJOI2019]唱.跳.rap和篮球 这么多人过没人写题解啊 那我就随便说说了嗷 这题第一步挺套路的,就是题目要求不能存在balabala的时候考虑正难则反,要求必须存在的方案数然后用总数减,往往 ...