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一个子类对象 二.虚函数 有没有一个解决方法,使我们只定义一个对象指针,就可以调用父类,以及各个子类的同名函数? 有解决方案,这个对象指针必须是一个父类类型 ...
随机推荐
- JSP将表单提交并在本页中显示
代码如下: <%@ page language="java" import="java.util.*" pageEncoding="UTF-8& ...
- SQL增加、删除、更改表中的字段名
1. 向表中添加新的字段 ) not null 2. 删除表中的一个字段 delete table table_name column column_name 3. 修改表中的一个字段名 alter ...
- groovy-位运算
从Groovy 1.0 beta 10开始,Groovy支持位运算:<<. >>, >>>, |, &, ^, and ~. 下表列出了位运算的操作符 ...
- mysql zip 版本配置方法
-\bin 指 C:\Program Files\MySQL\MySQL Server 5.6\bin 1.增加环境变量 "PATH"-"-\bin" 2.修改 ...
- gdb命令与调试方法
单线程 http://www.cnblogs.com/lidabo/p/5629830.html 编译程序一定要加-g选项 gcc -g test.c -o test 进入gdb调试:gdb 程序名 ...
- udf提权方法和出现问题汇总
一.适用条件 1.目标系统是Windows(Win2000,XP,Win2003): 2.你已经拥有MYSQL的某个用户账号,此账号必须有对mysql的insert和delete权限以创建和抛弃函数( ...
- phpcms 采集教程
Phpcms网站管理系统目前最新版本为Phpcms v9,作为国内主流CMS系统之一,目前已有数万网站的应用规模.那么其自带的采集模块功能如何呢,来看看吧. 文章采集 Phpcms v9默认内置有文章 ...
- Linq 中 表连接查询
public void Test(){ var query = from a in A join b in B on A.Id equals B.Id into c from d in c.Defau ...
- 工具类HttpServerUtility
在ASP.NET服务器上提供一个辅助的工具类HttpServerUtility,该类提供了一些处理请求的辅助方法. MapPath:计算网站中虚拟路径所对应的物理文件路径. HtmlEncode:将H ...
- c#接口和抽象类对比学习
什么是接口? 接口就是一种规范,协议(*),约定好遵守某种规范就可以写通用的代码. 定义了一组具有各种功能的方法.接口描述的是一种能力,具有这种能力的事物可以没任何关系.比如: public inte ...