正在悠闲地加载

2012国庆回来复习 笔记整理

内存分配有三种方式


1 静态分配,或者说静态存储区域分配。

就是说内存在程序编译的时候就已经分配好了,这款内存在程序整个运行期间都存在,如全局变量,static变量。

2 自动分配,或者说是在栈上分配。

比如在执行函数时,函数内局部变量的存储单元就是在栈上创建的,函数执行结束时,这些存储单元自动被释放。

3 堆上分配,或者说是动态内存分配。

那些用malloc和new申请来的内存,就是动态的,在堆上分配的。这些堆上分配出来的空间,由申请使用他们的那些人负责释放。

    补充:堆开辟内存空间时,是向着内存空间增加的方向的。而栈则是向下的,就是向着内存地址减少的方向。

重载,覆盖,隐藏

覆盖就是派生类函数覆盖基类的函数。满足覆盖的条件:派生类和基类的函数名相同,参数也相同,基类的函数必须有virtual。

隐藏是指派生类的函数屏蔽了与其同名的基类函数。满足隐藏的条件:派生类和基类的函数名相同,参数不同,不管有无virtual,都算隐藏。或者,派生类和基类函数名相同,参数相同,没有virtual,也算隐藏(有了virtual算什么,往上看)

重载就是有几个函数名相同,但是参数不同的函数。重载发生在相同范围,一定是同一个类。

 

 运算符重载 virtual关键字可有可无 operator不影响优先级

不是所有的运算符都能被重载,以下运算符就不行:

:: 作用域解析运算符

?: 条件运算符

. 直接成员运算符

.* 接解除类成员指针引用运算符

sizeof 

 

动态绑定 早期绑定

通过静态解析的基类指针来调用函数,都会调用基类函数。函数通过指针的静态,仅取决于指针的类型,而不取决与对象。

对于一个基类指针或者引用,定义时的类型称为静态类型,实际指向对象的类型称为动态类型。

在任意时候指针pbox都可以指向包含以box为其基类的 派生类的地址,这里的pbox 声明为box* 类型。

 

多态是通过基类指针、基类引用调用函数实现多态特性。

 

我们用virtual关键字来避开静态绑定。

动态绑定的条件,被调用函数必须是虚函数,必须通过基指针或者基类引用来调用。如果通过this指针间接调用虚函数也是动态调用。

 

动态调用必须是针对虚函数的调用,不能是针对一般成员函数的调用,并且就算把成员函数声明为虚函数,还要用基类指针或者基类引用直接调用,或者通过this指针间接调用这两个条件才能实现动态调用。

对于一般成员函数(非虚函数)必定是静态调用。

如果基类中把一个函数定义成虚函数,那么所有派生类中都有相同的返回值类型,函数签名,包括const也被认为是虚函数。反之,如果在派生类中,函数的返回值,签名,只有有一个和基类不同,在调用的时候就不会认为是基类的虚函数,此时执行静态调用。

如果虚函数在基类声明中带有默认参数值,那么在动态调用中,总是使用基类声明中的默认值。

 

有几个情况是静态调用函数:

设pbox是基类的指针,rbox是基类引用形参,volume()是虚函数。

使用类名和作用域运算符来强调调用指定类的虚函数,如:

pbox->Box::volume()

rbox.Box::volume()

使用对象名和成员运算符来调用虚函数是总是静态调用的

hardcase.volume(); 显式调用运算的hardcase的volume()

另外,用基类指针来调用一般成员函数(非虚函数)总是静态调用

 

基类指针和派生类指针 之间的 转换

派生类指针可以直接转化为基类指针

 

但是倒过来,基类指针不能隐式地转换成派生类指针,如果一定要,那么就是用强制类型转换,并且这种方式不保证一定成功。

 关于派生类和基类直接的转换代码

#include<iostream>
using namespace std;

class box
{
      public:
       virtual    void yoyo()
             {
                  cout<<"Box yoyo"<<endl;
              }
};

class carton:public box
{
      public:
             void yoyo()
             {
                  cout<<"carton yoyo"<<endl;
             }
};

class cerealpack:public carton
{
      public:
             void yoyo()
             {
                  cout<<"cerealpack yoyo"<<endl;
             }
};

int main()
{
    carton ca;
    carton *pca = &ca;

    cerealpack ce;
    cerealpack *pce = &ce;

    box bo;
    box* pbo = &bo;

    pce->yoyo();
    pce = static_cast<cerealpack*>(pbo);
    pce->yoyo();

return 0; }
posted @ 2012-10-23 16:45  仰望星空的耕田人  阅读(279)  评论(0编辑  收藏  举报