十一期间鸡啄米给大家做了关于生存期的课程,因为是假期,所以鸡啄米也就做了一节课程。今天继续给大家讲讲数据和函数的一些需要了解的具体知识。

       在结构化程序设计中,有人提出“数据结构+算法=程序设计”,数据结构就是数据的组织,算法是用函数实现的,可见数据和函数很早就被看作程序设计的重点了。面向对象程序设计中,这种观点应稍作一下修改:“数据结构+算法=对象”。就是数据和函数构成了类的对象。

       面向对象程序设计中,数据用来描述对象的属性,函数是行为,用来处理数据。将数据和函数封装到一个类里,类中的函数成员可以访问数据成员,函数成员之间可以实现数据共享。

       函数之间实现数据共享有以下几种方式:局部变量、全局变量、类的数据成员、类的静态成员和友元。如何共享局部变量呢?可以在主调函数和被调函数之间通过参数传递来共享。全局变量具有文件作用域,所以作用域中的各个函数都能共享全局变量。类的数据成员具有类作用域,能够被类的函数成员共享。这一讲鸡啄米先介绍这三种共享方式,类的静态成员和友元共享的方式后面两讲会讲到。

       1.局部变量

       鸡啄米前面简单提到过,局部变量其实一般就是说具有块作用域的变量。如果要在不同的块之间共享存储在局部变量中的数据,只能通过参数传递来实现。这种共享只能在主调函数和被调函数之间进行。因为局部变量具有块作用域,所以不同函数中的局部变量是互不可见的,这也是函数之间的一种数据隐藏,在结构化程序设计中这是实现数据隐藏的唯一方式。而在面向对象设计中主要靠封装来隐藏数据。

       2.全局变量

       全局变量具有文件作用域,在整个作用域中,除了定义了同名局部变量的块以外的地方都可以直接访问全局变量。不同的函数在不同的地方都能访问相同的全局变量,这样就实现了函数之间对全局变量的共享。

鸡啄米:C++编程入门系列之二十(C++程序设计必知:数据和函数)

       鸡啄米给大家一个全局变量的例子:

       #include <iostream>      
       using namespace std;
       int global;              // 定义全局变量global
       void f()
       {  
                 global=2;    // 给全局变量global赋值
       }
       void g()
       {  
                 cout<<global<<endl;  // 输出全局变量global的值
       }
       int _tmain(int argc, _TCHAR* argv[])
       { 
                 f();                 // 调用函数f给全局变量global赋值2
                g();                 // 输出全局变量global的值“2”
                return 0;
       }

       我们在进行软件开发的时候使用全局变量会很方便,不用那么多的传递参数,但是它也有很多负面作用。我们在多处使用了全局变量以后就不清楚此变量在哪些函数中使用过了,除非逐个查找,这样就会带来一个问题,如果全局变量要做一些大的改动,我们就不知道它会影响到哪些函数,这时就要通过大量的测试来排除全局变量变动带来的问题。

       结构化程序设计中,只能使用前面提到的局部变量参数传递和全局变量这两种方式共享数据。这两种方式各有利弊,局部变量隐藏性好,但是传递的时候会有很大的系统开销,所以一般只传递少量数据,大量数据通过全局变量的方式共享,但这又使得程序模块间耦合严重,扩展和维护都很困难。C++中可以通过具有文件作用域的全局对象来实现数据和函数的共享,这实际上也属于全局变量的范畴。

       3.类的数据成员

       类中封装了数据成员和函数成员。其中数据成员可以被同一个类中的所有函数成员访问,这样就实现了数据的共享。但是我们又可以通过设置访问控制权限,把这种共享限制到类的范围之内,这样类的数据成员对外界来说是隐藏的。也就达到了共享与隐藏的辩证结合。总起来说,要达成这样的效果需要把类的数据成员都设置为私有类型。

       鸡啄米再给出一个类的数据成员共享的例子:

       #include <iostream>
       using namespace std;
       class Example
       { 
       public:
                   void Init();
                   void Out();
       private:
                   int global;
       };
       void Example::Init()
       { 
                  global=2;
       }
       void Example::Out()
       {
                 cout<<global<<endl;
       }
       int _tmain(int argc, _TCHAR* argv[])
       {
                 Example  MyEmp;
                 MyEmp.Init();
                 MyEmp.Out();
                 return 0;
       }

       我们可以看出,类的数据成员global可以被类的函数成员Init和Out共享,但是在类外是不可以访问global的,只能通过接口Init和Out访问,实现了共享访问的权限控制,弥补了局部变量和全局变量的不足。这里的数据成员global发生类型等结构变化时,只会影响访问它的函数成员Init和Out,对程序其他地方没有影响,如果有修改的必要我们只需要修改Init和Out的实现就可以了。这样程序模块间的耦合性就大大降低,提高了程序的可扩展性和可维护性,能够大大提高软件开发效率。

       关于数据和函数的局部变量、全局变量和类的数据成员的共享鸡啄米就讲到这里了,后面会接着讲剩下的类的静态成员和友元的共享,谢谢大家。