首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 计算机考试 > 等级考试 > 复习指导 >

C和C++语言学习总结(二)(1)

2008-12-16 
函数参数传递;类重载、隐藏与覆盖区别;构造和析构的次序

    1、函数参数传递

  C++语言中,函数的参数和返回值的传递方式有三种:值传递、指针传递和引用传递.

  "值传递"的示例程序.由于Func1 函数体内的x 是外部变量n 的一份拷贝,

  改变x 的值不会影响n, 所以n 的值仍然是0.

  void Func1(int x)

  {

  x = x + 10;

  }

  …

  int n = 0;

  Func1(n);

  cout < < "n = " < < n < < endl; // n = 0

  "指针传递"的示例程序.由于Func2 函数体内的x 是指向外部变量n 的指

  针,改变该指针的内容将导致n 的值改变,所以n 的值成为10.

  void Func2(int *x)

  {

  (* x) = (* x) + 10;

  }

  …

  int n = 0;

  Func2(&n);

  cout < < "n = " < < n < < endl; // n = 10

  "引用传递"的示例程序.由于Func3 函数体内的x 是外部变量n 的引用,x

  和n 是同一个东西,改变x 等于改变n,所以n 的值成为10.

  void Func3(int &x)

  {

  x = x + 10;

  }

  …

  int n = 0;

  Func3(n);

  cout < < "n = " < < n < < endl; // n = 10

  内存分配方式

  分配方式 变量类型 分配特点

  静态存储区域分配 全局变量,static 变量 内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.

  栈分配 函数内局部变量 栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限.

  堆分配(亦称动态内存分配) new ,malloc分配 用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存.

  内存错误

  内存分配未成功,却使用了它.

  内存分配虽然成功,但是尚未初始化就引用它.

  内存分配成功并且已经初始化,但操作越过了内存的边界. 例如在使用数组时经常发生下标"多1"或者"少1"的操作.特别是在for 循环语句中,循环次数很容易搞错,导致数组操作越界.

  忘记了释放内存,造成内存泄露.

  放了内存却继续使用它.

  函数的return 语句写错了,注意不要返回指向"栈内存"的"指针"或者"引用",因为该内存在函数体结束时被自动销毁.

  程序中的对象调用关系过于复杂,实在难以搞清楚某个对象究竟是否已经释放了内存,此时应该重新设计数据结构,从根本上解决对象管理的混乱局面.

  使用free 或delete 释放了内存后,没有将指针设置为NULL.导致产生"野指针".

  malloc与new区别

  malloc 与free 是C++/C 语言的标准库函数,new/delete 是C++的运算符.它们都可用于申请动态内存和释放内存.

  对于非内部数据类型的对象而言,光用maloc/free 无法满足动态对象的要求.对象在创建的同时要自动执行构造函数, 对象在消亡之前要自动执行析构函数.由于malloc/free 是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free.因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete.注意new/delete 不是库函数. 3COME文档编辑

    2、类重载、隐藏与覆盖区别

  成员函数被重载的特征:

  (1)相同的范围(在同一个类中);

  (2)函数名字相同;

  (3)参数不同;

  (4)virtual 关键字可有可无.

  覆盖是指派生类函数覆盖基类函数,特征是:

  (1)不同的范围(分别位于派生类与基类);

  (2)函数名字相同;

  (3)参数相同;

  (4)基类函数必须有virtual 关键字.

  #include

  class Base

  {

  public:

  void f(int x) { cout < < "Base::f(int) " < < x < < endl; }

  void f(float x) { cout < < "Base::f(float) " < < x < < endl; }

  virtual void g(void) { cout < < "Base::g(void)" < < endl;}

  void h(float x) { cout < < "Base::h(float) " < < x < < endl;}

  void k(float x) { cout < < "Base::k(float) " < < x < < endl;}

  };

  class Derived : public Base

  {

  public:

  virtual void g(void) { cout < < "Derived::g(void)" < < endl;}

  void h(int x) { cout < < "Derived::h(int) " < < x < < endl; }

  void k(float x) { cout < < "Derived::k(float) " < < x < < endl;}

  };

  void main(void)

  {

  Derived d;

  Base*pb = &d;

  Derived *pd = &d;

  pb->f(42); // Base::f(int) 42 //重载

  pb->f(3.14f); // Base::f(float) 3.14 //重载

  pb->g(); // Derived::g(void) //覆盖

  pd->g(); // Derived::g(void) //覆盖

  pb->h(3.14f) // Base::h(float) 3.14 //隐藏

  pd->h(3.14f) // Derived::h(int) 3 //隐藏

  pb->k(3.14f) // Base::k(float) 3.14 //隐藏

  pd->k(3.14f) // Derived::k(float) 3.14 //隐藏

  }

热点排行