C++编程笔记-特性

一、虚函数

  虚函数一般是定义在基类中声明为 virtual 并在一个或多个派生类中被重新定义的成员函数,用法格式为:virtual 函数返回类型 函数名(){}。虚函数的作用就是用于运行多态性,即在类继承中,基类和派生类会有相同的成员函数,指向基类的指针在操作它的多态类对象时(这个指针可以指向基类的对象,也可以指向派生类的对象),会根据不同的类对象,调用其相应的函数,这个函数就是虚函数。一般的成员函数(包括虚函数)可以只有声明,前提是在应用中不能调用该函数,否则会因找不到定义产生连接错误!

class A{
   
public:
    void function(){
   }
}
class B : public A{
   
public:
    void function(){
   }
}
int main(){
    A a;
    B b;
    A *p1 = &a;
    A *p2 = &b;
    p1->function();
    p2->function();
}

  在上面的代码中我们定义了基类A和派生类B,若function函数不是虚函数时,则输出时p1和p2调用的都是基类A的函数function,因为它们都是A类型的指针,若是在基类A的function函数前面添加virtual使之成为虚函数,则输出时p1和p2调用的函数就分别是A和B的function函数了。这就是虚函数的作用,即在基类指针指向多态对象时,根据对象所属的类来调用相应的函数。
虚函数使用事项:
   1. 在基类用virtual声明成员函数为虚函数。 这样就可以在派生类中重新定义此函数,为它赋予新的功能,并能方便地被调用。在类外定义虚函数时,不必再加virtual。
   2. 在派生类中重新定义此函数,要求函数名、函数类型、函数参数个数和类型全部与基类的虚函数相同,并根据派生类的需要重新定义函数体。C++规定,当一个成员函数被声明为虚函数后,其派生类中的同名函数都自动成为虚函数。因此在派生类重新声明该虚函数时,可以加virtual,也可以不加,但习惯上一般在每一层声明该函数时都加virtual,使程序更加清晰。如果在派生类中没有对基类的虚函数重新定义,则派生类简单地继承其直接基类的虚函数。
   3. 定义一个指向基类对象的指针变量,并使它指向同一类族中需要调用该函数的对象。
通过该指针变量调用此虚函数,此时调用的就是指针变量指向的对象的同名函数。通过虚函数与指向基类对象的指针变量的配合使用,就能方便地调用同一类族中不同类的同名函数,只要先用基类指针指向即可。如果指针不断地指向同一类族中不同类的对象,就能不断地调用这些对象中的同名函数。
此节部分参考内容及详细实例可以参考《什么是C++虚函数、虚函数的作用和使用方法》
C++的多态性更多内容参考[C++之多态性与虚函数](http://www.cnblogs.com
只有类的成员函数才能说明为虚函数,因为虚函数仅适合用与有继承关系的类对象,所以普通函数不能说明为虚函数。
静态成员函数不能是虚函数,因为静态成员函数的特点是不受限制于某个对象。
内联(inline)函数不能是虚函数,因为内联函数不能在运行中动态确定位置。即使虚函数在类的内部定义,但是在编译的时候系统仍然将它看做是非内联的。
构造函数不能是虚函数,因为构造的时候,对象还是一片位定型的空间,只有构造完成后,对象才是具体类的实例。析构函数可以是虚函数,而且通常声名为虚函数。

纯虚函数:即基类中没有给出有意义的实现的虚函数,类似于Java中的接口函数。纯虚函数一般都直接=0,表明他的直接功能由子类进行定义,他是虚函数的其中一种。派生类中必须要实现纯虚函数。
纯虚类:只要有一个纯虚函数,就称为纯虚类也叫抽象类,纯虚类不可以定义一个对象。
Java有关虚函数等于C++的区别:在Java中一般没有虚函数的概念,Java继承中最常见的概念就是抽象类和接口,关于两者区别联系参考:JAVA – 虚函数、抽象函数、抽象类、接口

二、虚析构函数

  C++中与构造函数对应的就是析构函数了,我们都知道析构函数的作用就是用于释放内存清除不需要的数据空间。一般是在构造函数前加一个~就是析构函数了,这里要讲的虚析构函数就是在析构函数前再加上virtual。虚析构函数的作用就是:为了当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用。一般来讲也只有当一个类用作基类时才把析构函数写成虚析构函数。其实这就是虚函数在析构函数上的一种应用,详细的讲解可参考C++中虚析构函数的作用
  一般来说,带多态性质的基类应该声明一个virtual析构函数,一个类如果不是用于基类或是多态的化,不应该声明virtual析构函数。常见的string,STL都不被设计为基类使用,即在这些类中,不存在virtual析构函数,最好不要用来当作基类进行派生。

三、#program once

  在有些代码中可以看到这一句:#program once,这个意思就是当前文件不会被包含多次,当前文件应用上指的是物理上的一个文件,它的作用于最常见的#ifndef #define #endif作用是相似的。具体区别参考:#ifndef 与 #program once 的区别

四、typedef #define

  typedef和#define都可以用来定义别名,但两者的顺序刚好相反,如把INT定义成C++的数据类型int,即INT为int的别名,则两种写法分别为:
  typedef int INT;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值