c++ 继承 虚函数与多态性 重载 覆盖 隐藏
http://blog.csdn.net/lushujun2011/article/details/6827555
2011.9.27
1)
定义一个对象时,就调用了构造函数。如果一个类中没有定义任何构造函数,那么C++编译器就会在某种情况下为该类提供一个默认的不带参数的构造函数。
只要一个类中定义了一个构造函数,不管这个构造函数是不是默认的,C++编译器都不会再提供默认的构造函数,所以,如果定义了自己的构造函数还想调用默认的构造函数的话,必须再重新定义一个默认的构造函数。
2)析构函数不允许带参数,并且一个类中只能有一个虚构函数。
3)在类中定义成员变量时,不能直接给成员变量赋初值!!!
4)函数的重载条件:
1、在同一类中 2、同名函数 3、函数参数类型或者参数的个数不同
注意:返回值不同的同名同参函数不能构成重载
特例:函数重载时,要注意函数带有默认参数这种情况
void output(int a , int b = 5);
void output(int a);
调用时,会产生二义性
5)构造函数顺序:父类->子类
析构函数顺序:子类->父类
6)//在main函数里定义一个子类实例时,子类先调用父类带参数的构造函数,
public:
fish():animal(400,300)
{
cout<<"fish construct"<<endl;
}
7)多重继承:
class B : public C ,public D //B多重继承与C与D,用逗号隔开各个基类便可
继承表说明顺序:C在D之前,构造函数调用先,是按基类表的说明顺序进行初始化的。析构函数则相反。
注意多重继承中的函数二义性问题:
例如:C、D类都有同名函数(形参亦同)output(),B多重继承与C、D,则调用a.output时,则编译不过,出现ambiguous多义性问题
8)
animal *pAn; // 父类指针,父类animal有breathe()函数
fish fh; //子类实例,子类重定义了breathe()函数
pAn = &fh; //父类指针指向子类,编译器把子类隐含地转化做父类animal类型,
fn(pAn); // fn是全局函数,这里调用的是父类animal的breathe()函数
上述父类的breathe()若改为虚函数,则调用的是对象的实际类型,也就是pAn是fish的类型,所以最终调用的是子类的breathe()
9)虚函数与多态性
加virtual关键字的函数为虚函数,它体现了C++中的多态性,在编译的时候,利用迟绑定技术,也就是编译时并不确定调用哪个函数,而是在运行时
才依据对象类型来确定调用哪个函数,C++的多态性用一句话概括:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时就会根据对象的实际类型来确定调用相应的函数。
char *p = new char
new指令分配的对象是在堆中分配的,它本质上是执行了一次malloc()调用,并调用了一次构造函数。由new得到的,只是对象的指针,而不是对象本身。更重要的是由new 得到的对象,原则上需要delete。
基本上可以理解为 定义的时候(int a;)分配了内存。但这样说过于简单,并且很不准确。
对于全局变量,变量事实上是预分配的,在程序调入内存,还没执行之前就分配了。
对于静态变量,也是预分配的,但是真正的生效是在第一次执行定义的时候(注意这句话)。
对于自动变量,每次执行定义指令的时候(int a;)都会分配内存。该内存是在栈中分配的。
还有种寄存器变量,基本和自动变量相同。
/*
函数的覆盖:1)在父类和子类中 2)完全相同的函数(形参亦同)3)都是虚函数
函数的隐藏:1.1)在子类和父类中 2)同名函数(形参同) 3)不是虚函数
2.1)在子类和父类中 2)同名函数(形参不同)
简单的区分:同名函数不是函数的覆盖就是函数的隐藏。
函数的覆盖与虚函数多态性联系在一起,与父类子类有关。
函数的多态性是由虚函数体现的。
函数的重载(同名不同参函数)则是在同一个类之中。
有纯虚函数的基类叫做抽象类,它不能定义一个实例,因为它只为派生类服务,
而继承的派生类必须有其函数的具体实现,否则亦是一个抽象类不能定义实例。
#include <iostream>
#include <stdio.h>
using namespace std;
class Base
{
public:
Base(){
cout << "Base()" << endl;
}
virtual ~Base(){
cout << "~Base()" << endl;
}
virtual void xfn(int i) {cout<<"Base::xfn(int i):" << i <<endl; }
void yfn(float f) {cout<<"Base::yfn(float f):" << f <<endl;}
void zfn() {cout<<"Base::zfn()"<<endl;}
};
class Derived:public Base
{
public:
Derived(){
cout << "Derived()" << endl;
}
~Derived(){
cout << "~Derived()" << endl;
}
void xfn(int i) {cout<<"Derived::xfn(int i):" << i <<endl; }//覆盖了基类的xfn函数
//void yfn(int c) {cout<<"Derived::yfn(int c):" << c <<endl;} //隐藏了基类的yfn函数
void yfn(float c) {cout<<"Derived::yfn(float c):" << c <<endl;} //隐藏了基类的yfn函数
void zfn() {cout<<"Derived::zfn()"<<endl;} //隐藏了基类的zfn函数
};
int main()
{
printf("$$$$$$$$$$$$$$$$%s %d\n", __func__, __LINE__);
Derived d;//B D
printf("$$$$$$$$$$$$$$$$%s %d\n", __func__, __LINE__);
Base *pB = &d;//
printf("$$$$$$$$$$$$$$$$%s %d\n", __func__, __LINE__);
Derived *pD = &d;//
printf("$$$$$$$$$$$$$$$$%s %d\n", __func__, __LINE__);
pB->xfn();//Dx 5
printf("$$$$$$$$$$$$$$$$%s %d\n", __func__, __LINE__);
pD->xfn();//Dx 5
printf("$$$$$$$$$$$$$$$$%s %d\n", __func__, __LINE__);
pB->yfn(3.14f);
printf("$$$$$$$$$$$$$$$$%s %d\n", __func__, __LINE__);
pD->yfn(3.14f);
printf("$$$$$$$$$$$$$$$$%s %d\n", __func__, __LINE__);
pB->zfn();
printf("$$$$$$$$$$$$$$$$%s %d\n", __func__, __LINE__);
pD->zfn();
printf("$$$$$$$$$$$$$$$$%s %d\n", __func__, __LINE__);
/*why not the flowlling,do you know?
delete pD;
printf("$$$$$$$$$$$$$$$$%s %d\n", __func__, __LINE__);
delete pB;
printf("$$$$$$$$$$$$$$$$%s %d\n", __func__, __LINE__);
*/
;
}
*/
#include <iostream>
using namespace std;
class Base
{
public:
virtual void xfn(int i) {cout<<"Base::xfn(int i)"<<endl; }
void yfn(float f)
{cout<<"Base::yfn(float f)"<<endl;}
void zfn() {cout<<"Base::zfn()"<<endl;}
};
class Derived:public Base
{
public:
void xfn(int i)
{cout<<"Derived::xfn(int i)"<<endl; }//覆盖了基类的xfn函数
void yfn(int c)
{cout<<"Derived::yfn(int c)"<<endl;} //隐藏了基类的yfn函数
void zfn() {cout<<"Derived::zfn()"<<endl;} //隐藏了基类的zfn函数
};
void main()
{
Derived d;
Base *pB = &d;
Derived *pD = &d;
pB->xfn(5);
pD->xfn(5);
pB->yfn(3.14f);
pD->yfn(3.14f);
pB->zfn();
pD->zfn();
//system("pause");
}
c++ 继承 虚函数与多态性 重载 覆盖 隐藏的更多相关文章
- [022]c++虚函数、多态性与虚表
原文出处:http://my.oschina.net/hnuweiwei/blog/280894 目录[-] 多态 虚函数 纯虚函数 虚表 一般继承(无虚函数覆盖) 一般继承(有虚函数覆盖) 多重继承 ...
- 【足迹C++primer】52、,转换和继承虚函数
转换和继承,虚函数 Understanding conversions between base and derived classes is essential to understanding h ...
- C++ 由虚基类 虚继承 虚函数 到 虚函数表
//虚基类:一个类可以在一个类族中既被用作虚基类,也被用作非虚基类. class Base1{ public: Base1(){cout<<"Construct Base1!&q ...
- (C/C++学习)5.C++中的虚继承-虚函数-多态解析
说明:在C++学习的过程中,虚继承-虚函数经常是初学者容易产生误解的两个概念,它们与C++中多态形成的关系,也是很多初学者经常产生困惑的地方,这篇文章将依次分别对三者进行解析,并讲述其之间的联系与不同 ...
- 继承虚函数浅谈 c++ 类,继承类,有虚函数的类,虚拟继承的类的内存布局,使用vs2010打印布局结果。
本文笔者在青岛逛街的时候突然想到的...最近就有想写几篇关于继承虚函数的笔记,所以回家到之后就奋笔疾书的写出来发布了 应用sizeof函数求类巨细这个问题在很多面试,口试题中很轻易考,而涉及到类的时候 ...
- C++重载覆盖隐藏
写一个程序,各写出重载覆盖 1 // // main.cpp // 2013-7-17作业2 // // Created by 丁小未 on 13-7-17. // Copyright (c) 201 ...
- c++虚函数,纯虚函数,抽象类,覆盖,重载,隐藏
C++虚函数表解析(转) ——写的真不错,忍不住转了 http://blog.csdn.net/hairetz/article/details/4137000 浅谈C++多态性 http://bl ...
- 继承自TWinControl的控件不能在设计期间接受子控件,用代码设置子控件却可以(它的自绘是直接改写PaintWindow虚函数,而不是覆盖Paint函数——对TWinControl.WMPaint又有新解了)
这个控件直接继承自TWinControl,因此不是改写Paint;函数,而是直接改写PaintWindow虚函数,它在VCL框架里被直接调用,直接就把自己画好了(不用走给控件Perform(WM_Pa ...
- C++基础知识 基类指针、虚函数、多态性、纯虚函数、虚析构
一.基类指针.派生类指针 父类指针可以new一个子类对象 二.虚函数 有没有一个解决方法,使我们只定义一个对象指针,就可以调用父类,以及各个子类的同名函数? 有解决方案,这个对象指针必须是一个父类类型 ...
随机推荐
- python 与 mysql
1.开发环境: 1)CLion-2016.1.3 C/C++ 与 Python 混合编程 IDE,先安装好以下 2) 3) 编译器再关联 2)tdm-gcc-4.8.1-3 C/C++ 编译器 3)W ...
- linux 运行级别与chkconfig
一.Linux的运行级别 在装MySQL的时候,才知道了Linux的运行级别这么一回事.汗…自己太水了…下面总结一下: 什么是运行级别呢?简单点来说,运行级别就是操作系统当前正在运行的功能级别.级别是 ...
- 兼容amd,commonjs和browser的模块写法
从uuid.js中抽出来的写法. (function() { var _global = this; // Export public API var obj = {}; obj.attr = fun ...
- VO(DTO)模式在架构设计中是否需要
DTO(VO):也就是一般意义上的VO,封装后的对象.一般用于Web层—Service层间的数据传输入. PO:也就是一般概念上的Domain Object,如hibernate 中的Entity.一 ...
- GTP V0 和 GTP V1
GTP概述 GTP(GPRS Tunnelling Protocol)协议应用在SGSN 和GGSN 之间,为各个移动台(MS) 建立GTP 通道,GTP 通道是 GPRS服务节点(GSN) 之间的安 ...
- Linux时间不准确的问题![转]
Linux时间不准确的问题![转] 安装完系统发现时间与现实时间相差+8小时,经分析由以下产生.我们在安装时选择的是上海,而centos5把bios时间认为是utc时间,所以+8小时给我们.这个时候的 ...
- (转)也谈基于NodeJS的全栈式开发(基于NodeJS的前后端分离)
原文链接:http://ued.taobao.org/blog/2014/04/full-stack-development-with-nodejs/ 随着不同终端(pad/mobile/pc)的兴起 ...
- TYVJ1460 旅行
描述 A国有n座城市,每座城市都十分美,这使得A国的民众们非常喜欢旅行.然而,A国的交通十分落后,这里只有m条双向的道路,并且这些道路都十分崎岖,有的甚至还是山路,只能靠步行.通过每条道路的长度.泥泞 ...
- 如何将北京时间批量转为Unix时间?用Excel!
前面我们说过Unix时间戳转换怎样在Excel批量修改,有些人就想如果有特殊需求,那能不能批量将北京时间批量转成unix时间呢?能!用Excel就可以实现!跟ytkah一起试试吧. 将unix时间戳转 ...
- Valid Pattern Lock(dfs + 暴力)
Valid Pattern Lock Time Limit: 2 Seconds Memory Limit: 65536 KB Pattern lock security is genera ...