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( ...
随机推荐
- css吃豆人动画
一. Css吃豆人动画 1. 上半圆:两个div,内部一个圆div,外部设置宽高截取半圆 外部div动画:animation: 动画样式 1s(时长) ease(动画先低速后快速) infinite( ...
- CentOS7时区和时间设置
[root@saltstack-master ~]# timedatectl set-timezone Asia/Shanghai [root@saltstack-master ~]# ln -sf ...
- C语言四
c语言循环结构 为什么用循环? C语言中的循环主要分为三种:while循环,do...while循环 for循环 while循环:先判断条件是否成立,如果条件成立将执行其下的循环体,如果条件不成立一次 ...
- [Wpf学习] 1.传说中的Main
原来的C#程序都有Main的,现在用vs新建一个Wpf项目,启动似乎变成App.xmal,前期项目中为了获取启动参数,很是折腾了一番: 1.先是修改App.xaml,添加StartUp事件 <A ...
- java设计模式--迪米特法则
基本介绍 1.一个对象应该对其他对象保持最少的了解 2.类与类关系越密切,耦合度越大 3.迪米特法则又叫最少知道原则,即一个类对自己依赖的类知道的越少越好.也就是说,对于被依赖的类不管多么复杂,都尽量 ...
- 常见CSS3选择器和文本字体样式汇总
常见的CSS3选择器包含:常用基本.属性.伪类.层级(组合)选择器,具体使用情况建议先阅读css选择器四大类:基本.组合.属性.伪类对于选择器的使用有一个基本了解,选择器的作用在于通过它找到元素,并且 ...
- mysql添加索引(建表之后)
一.使用ALTER TABLE语句创建索引 语法如下: alter table table_name add index index_name (column_list) ; alter table ...
- CentOS、Ubuntu的安装
Linux使用最广泛的2个发行版:CentOS.Ubuntu. CentOS安全性高,常用作企业的服务器,Ubuntu常用作个人桌面. 常见的虚拟机有2个: VM VirtualBox,这个是Orac ...
- Educational Codeforces Round 32 E 二分
题意:从数组中选几个(任意),使他们的和modm的值最大 题解:我一开始是直接暴力写,然后就会t 其实这题可以用二分的方法写,一半数组的值用来遍历,一般数组的值用来查询. 二分查询就能把时间继续缩短 ...
- docker笔记(2)
docker笔记(2) 常用命令和操作 1. 镜像操作 操作 命令 说明 检索 docker search 关键字 eg:docker search redis 我们经常去docker hub上检索镜 ...