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一个子类对象 二.虚函数 有没有一个解决方法,使我们只定义一个对象指针,就可以调用父类,以及各个子类的同名函数? 有解决方案,这个对象指针必须是一个父类类型 ...
随机推荐
- ubuntu 12.04安装telnet和ssh服务
ubuntu安装telnet服务 1. sudo apt-get install xinetd telnetd sudo vi /etc/inetd.conf并加入以下一行,假如没有发现这个文件,自己 ...
- 轻量级应用开发之(08)UITableView
一 UITableView基本介绍 在众多移动应⽤用中,能看到各式各样的表格数据 . 在iOS中,要实现表格数据展示,最常用的做法就是使用UITableView,UITableView继承自UISc ...
- JS 在线网站
JS 在线压缩网站 国内压缩js网站http://tool.css-js.com/ uglifyjs 压缩js网站http://lisperator.net/uglifyjs JS在线格式化网站 ht ...
- easyui之datagrid的使用
http://www.cnblogs.com/ruanmou001/p/3840954.html 一.神马是easyui jQuery EasyUI是一组基于jQuery的UI插件集合,而jQuery ...
- 通用跨站脚本攻击(UXSS)
有同学问,用百度搜索了下,发现国内相关介绍基本是没有,就写篇文章来介绍下.不过看到有现成的介绍,就拿来翻译修改下.本文的内容主要翻译来自该文章,把一些没必要的话给删了,做了一些整理修改,然后补充一些案 ...
- WebSocket 基本函数
1.构造函数 WebSocket(char *host); 创建一个websocket对象,接受一个参数以ws://靠头,就像发起一个HTTP请求一样用http://开头 var ws=new W ...
- ARP欺骗病毒,网页“篡改”,注入iframe代码!
---------------权威资料看这里--------------- 清华大学信息网络工程研究中心-中国教育和科研计算机网应急响应组<ARP 欺骗网页劫持攻击分析>PDF文件,直接I ...
- NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool
错误:Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/pool/impl ...
- ctags 的最简单使用
vim插件ctags的安装和使用 2013-11-19 20:47 17109人阅读 评论(0) 收藏 举报 分类: 开发工具(3) linux编程(9) c/c++编程(11) 版权声明:本 ...
- 如何修改ubuntu系统的电脑名(主机名)
在按照ubuntu系统时,会提示你给电脑填写一个名字,可能当时你没有想好,就随便填写了一个,可是以后就又有新的想法,想重新更换一个名字,该怎么办呢? 其实很简单.按照下面的步骤即可. 进去后,修改完, ...