C++基类、派生类、虚函数的几个知识点
1.尽管派生类中含有基类继承来的成员,但派生类初始化这部分变量需要调用基类的构造函数。
class A
{
private:
int x;
virtual void f(){cout<<"A f"<<endl;}
public:
A(/* args */){x=;cout<<"A构造"<<endl;}
~A(){}
friend void p(const A& a){cout<<a.x;}
};
class B:A{
public:
void f() override {cout<<"B f"<<endl;}
operator A()const {}
};
int main()
{
B x;
system("pause");
return ;
}

2.如果基类定义了一个静态成员,则整个继承体系中只存在该成员的唯一定义。并且不论基类派生出多少派生类,该静态成员只存在唯一实例。
并且属性也一致。基类中某静态成员是public,派生类中也是public。如果基类中是private,那么派生类也无法调用该静态成员。
/* 基类的静态成员 */ #include<iostream> using namespace std; class base
{
public:
static int num; base()
{
num+=;
} ~base()
{
num-=;
}
}; // 基类定义的静态成员,被所有派生类共享
// 起到计数器的作用,自身还有所有派生类对象的个数
// 遵循私有 公有 保护的继承机制 访问不同
// 可以通过父类 子类对象访问 还可以通过父类 子类类名访问
int base::num = ;// 类的静态成员 class basenew : public base
{ }; class basenewx : public basenew
{ }; void main()
{
basenew *p = new basenew[]; base *p1 = new base[] basenewx *p2 = new basenewx[]; cout << p->num << endl;//
cout << p1->num << endl;//
cout << p2->num << endl;// cin.get();
}
3.如果不想让某个类被继承,在类名后加final关键字。

final除了可以修饰类外,还可以修饰成员函数。还可以指明某个基类的虚函数不能被其派生类版本覆盖,如下:
首先要明确覆盖(override)与重载(overload)的定义,区别出什么是覆盖和重载:
覆盖就是派生类中虚成员函数覆盖基类中同名且参数相同的成员函数。
class A
{
public:
A(/* args */){}
virtual void f()final {}
virtual ~A(){}
};
class B:public A{
public:
void f(int x){}//重载(overload)
void f(){} //覆盖(override,非法,因为A中的f声明了final)
};
4.派生类对象是基类对象,派生类中包含有基类的成员。基类对象不是派生类对象,它不能包含派生类型的成员。
派生类可以向基类转化(仅限指针和引用),基类不能向派生类转化(毕竟派生类有多余的数据,基类没法自己生成)
如果用派生类对象为一个基类对象初始化或者赋值,只有其中的基类部分会被拷贝/移动/赋值,它的派生类部分会被忽略。
class A
{
private:
int x;
public:
A(/* args */){x=;cout<<"A构造"<<endl;}
virtual ~A(){}
};
class B:public A{ };
int main()
{
A x;
B y;
A* p=&y;//正确,将基类指针指向派生类变量,派生类指针隐式转换为基类指针。
B* q=&x;//错误
system("pause");
return ;
}
5.动态绑定(即dynamic bninding)只有当我们通过指针或者引用调用虚函数时才会发生。
由于继承导致对象的指针和引用具有两种不同的类型:静态类型和动态类型。
静态类型:指针或者是引用声明时的类型。
动态类型:由实际指向的类型确定。
其中静态类型编译时就已经确定,动态类型只有到运行的时候才能知道。所以如果用普通类类型调用虚函数,编译时就会把要调用的虚函数版本确定下来。
class A
{
public:
A(/* args */){}
virtual void f(){cout<<"基类的f"<<endl;}
virtual ~A(){}
};
class B:public A{
public:
void f(){cout<<"派生类的f"<<endl;}
};
void F(A& p){
p.f();
}
int main()
{
A x;
B y;
F(x);
F(y);
system("pause");
return ;
}

可以看到同一个函数F,因为调用不同类型实参,最终在内部调用了不同版本的f函数,这就是动态绑定。
如果F的形参改成普通类型,那么两次都会调用基类的f函数,其中F(y)会把y隐式类型转换为一个A类型的临时变量传给形参。

6.如果一个派生类虚函数需要调用其基类版本,但没有使用“基类::”修饰,则运行时该调用会被解析为对其自身的调用,这将导致无限递归。
7.派生类中的虚函数可以在形参后加override,显式告知编译器该虚函数覆盖了其基类版本。
C++基类、派生类、虚函数的几个知识点的更多相关文章
- C++:抽象基类和纯虚函数的理解
转载地址:http://blog.csdn.net/acs713/article/details/7352440 抽象类是一种特殊的类,它是为了抽象和设计的目的为建立的,它处于继承层次结构的较上层. ...
- C++基础知识 基类指针、虚函数、多态性、纯虚函数、虚析构
一.基类指针.派生类指针 父类指针可以new一个子类对象 二.虚函数 有没有一个解决方法,使我们只定义一个对象指针,就可以调用父类,以及各个子类的同名函数? 有解决方案,这个对象指针必须是一个父类类型 ...
- (转)(C++)关于抽象基类和纯虚函数
★抽象类:一个类可以抽象出不同的对象来表达一个抽象的概念和通用的接口,这个类不能实例化(创造)对象. ★纯虚函数(pure virtual):在本类里不能有实现(描述功能),实现需要在子类中实现.例: ...
- C++学习笔记(十二):类继承、虚函数、纯虚函数、抽象类和嵌套类
类继承 在C++类继承中,一个派生类可以从一个基类派生,也可以从多个基类派生. 从一个基类派生的继承称为单继承:从多个基类派生的继承称为多继承. //单继承的定义 class B:public A { ...
- C++入门经典-例8.9-抽象类,纯虚函数,创建纯虚函数
1:包含有纯虚函数的类称为抽象类,一个抽象类至少具有一个纯虚函数.抽象类只能作为基类派生出的新的子类,而不能在程序中被实例化(即不能说明抽象类的对象),但是可以使用指向抽象类的指针.在程序开发过程中并 ...
- 继承虚函数浅谈 c++ 类,继承类,有虚函数的类,虚拟继承的类的内存布局,使用vs2010打印布局结果。
本文笔者在青岛逛街的时候突然想到的...最近就有想写几篇关于继承虚函数的笔记,所以回家到之后就奋笔疾书的写出来发布了 应用sizeof函数求类巨细这个问题在很多面试,口试题中很轻易考,而涉及到类的时候 ...
- 自绘CListCtrl类,重载虚函数DrawItem
//自绘CListCtrl类,重载虚函数DrawItem void CNewListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { // TOD ...
- C++中继承 声明基类析构函数为虚函数作用,单继承和多继承关系的内存分布
1,基类析构函数不为虚函数 #include "pch.h" #include <iostream> class CBase { public: CBase() { m ...
- c++ 类内部函数调用虚函数
做项目的过程中,碰到一个问题. 问题可以抽象为下面的问题: 普通人吃饭拿筷子,小孩吃饭拿勺子. class People { public: void eat() { get_util_to_eat( ...
随机推荐
- 杭电--1009 C语言实现
思路:要用有限的猫粮得到最多的javabean,则在房间中得到的javabean比例应尽可能的大. 用一个结构体,保存每个房间中的javabean和猫粮比例和房间号,然后将结构体按比例排序,则从比例最 ...
- 意法半导体STM32MP157A MPU加持,米尔科技首款ST Linux开发板MYD-YA157C评测
ST公司去年推出了MPU系列芯片,MPU系列不同于以往产品,它既包含有ARM公司Cortex M 单片机核心,也包含有ARM公司Cortex A 应用处理器核心,以期将STM32单片机产品优势扩展到更 ...
- css沉默
css变色龙实现. ==== css 1 水平居中和垂直居中. 2 css布局方式. 3 你写过UI框架么.
- js中的innerHTML,innerText,value的区别
首先先说一下 我自己认为的 innerHTML,innerText,value的区别 innerHTML 是在控件中加html代码 就是设置一个元素里面的HTML eg: <html> & ...
- C#设计模式学习笔记:(13)模板方法模式
本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7837716.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第一个模式--模 ...
- Tomcat 核心配置
tomcat的核心配置在conf/server.xml中. <Server> 根元素 <Server>即Catalina Servlet组件. <Server por ...
- 聊聊spring之bean对象的实例化过程
在spring实例化 之前bean对象封装成 beanDefinition 对象 想了解详情的请参考上一篇文章 好了 我们聊聊 Bean 的实例化过程的几个重要角色 BeanDefinitionReg ...
- spring cloud微服务快速教程之(五) ZUUL API网关中心
0-前言 我们一个个微服务构建好了,外部的应用如何来访问内部各种各样的微服务呢?在微服务架构中,后端服务往往不直接开放给调用端,而是通过一个API网关根据请求的url,路由到相应的服务.当添加API网 ...
- 最新咕咆+鲁班+图灵+享学+蚂蚁+硅谷+源码 Java架构师资料《Java架构师VIP课程》
最新的Java架构师完整资料,完整视频+源码+文档. 每一套都是一百多个G的资料,无密. JAVA架构师全套课程 咕泡学院互联网架构师第一期 咕泡学院互联网架构师第二期 咕泡学院互联网架构师第三期 博 ...
- Elasticsearch之文档的增删改查以及ik分词器
文档的增删改查 增加文档 使用elasticsearch-head查看 修改文档 使用elasticsearch-head查看 删除文档 使用elasticsearch-head查看 查看文档的三种方 ...