紫影龙的编程日记 —— 认识了解函数 ( 方法 )

       今天是我学习编程开发的第三天啦~ 今天我主要学习的内容是 函数哦~  

       看到 “函数” 这2个字,相信大多数刚开始学习编程开发的朋友都会觉得头痛吧~

       嘿嘿,其实此 “函数” 非彼 “函数” ,我们这里说的 “函数” 实际上也可以叫做 “方法” 。

      一个较大的程序一般分为若干个程序块,每一个模块用来实现一个特定的功能。所有的高级语言中都有子程序这个概念,用子程序实现模块的功能。比如说,在 C++ 中,子程序的作用是由一个主函数 ( 入口函数 ( 方法 ) ) 和若干个函数 ( 方法 ) 构成。通常由主函数调用其他函数,其他函数之间也可以互相调用。除了入口函数之外,同一个函数可以被一个或多个函数调用任意多次。在程序设计中,我们常将一些常用的功能模块编写成函数,放在函数库中供公共选用。要善于利用函数,减少重复编写程序段的工作量。

在 C++ 程序设计中,函数可以分为两类:带参数的函数和不带参数的函数。这两种参数的声明、定义也不一样。
 
有返回值且带有 ( 一个 ) 参数的函数的声明:
类型名标识符 + 函数名 + ( 类型标示符 + 参数 )
{
// 程序代码...
return 返回值;
}

没有返回值 (void) 且不带参数的函数的声明:
void+ 函数名() //无值型(void) + 函数名()
{
// 程序代码...
}

花括号内为 函数体  若有多个参数,则用逗号分隔。例如 void Function ( int Num, CString Name ) {......}  
PS:在开发中使用的都是英文状态下的标点符号。

没有返回值的类型名为"void", 整数类型 int 的返回值为整数类型, 字符串类型 CString 的返回值为字符串类型以此类推……
类型名有:void int long float CString char ……等等。  除了void 类型之外,其他类型都必须返回该类型的值。
在 C++ 中,凡不加返回值类型限定的函数,都会被编译器作为返回 整型 值 ( int ) 处理。

C++中函数的调用:函数必须声明 ( 定义 ) 后才可以被调用。调用格式为:函数名 ( 实参 )
调用时函数名后的小括号中的实参必须和声明函数时的函数括号中的形参个数相同。
有返回值的函数可以进行计算,也可以做为右值进行赋值。
函数在定义时可以预先定义出默认的形参值。调用时如果给出实参,则用实参初始化形参,如果没有给出实参,则采用预先定义的默认形参值。

   对象作为函数参数

    对象可作为实参传递给函数,可按传值方式和引用方式进行传递。一般按引用方式较多:
    –按值方式需要额外的时间和内存空间;
    –使用对象引用参数比使用指针参数更为简单。


 函数重载

重载函数必须:函数名相同,函数的作用域相同,函数的参数个数或参数类型不同。
使用重载函数时应注意:

⑴只有返回值不同,不能成为重载函数。

    int test(inta,int b);

    double test(inta,int b);  //错误,只有返回值不同,不能成为重载函数。


⑵使用带缺省值的函数时,可能引发错误。如:

    int test(inta, int b = 0);

    int test(int a);

当用一个实参调用该函数时,如test(2),则会出现调用歧义性。


      要说 MFC 里最重要,使用频率最多的,就要属构造函数和折构函数啦~ 让我们来认识一下。

      构造函数 ( 常用于对象的初始化 )

      一个类提还供一些特殊的函数,创建新对象时,它们会被调用,那就是构造函数 (Constructor) 。用来执行初始化操作 ( 如 对象的数据成员 ) 。
     若要为类中的 private ( 私有 ) 数据成员进行初始化,在声明对象的时候就需要使用 构造函数 来完成。
     对象在被创建时,系统为对象分配存储空间,调用构造函数(可以是默认构造函数),执行构造函数体中的代码。
  每个类必须有构造函数( 包括默认的构造函数 ),没有构造函数就不能创建对象。

构造函数是一种特殊的函数,与其他函数有以下三点不同:
–构造函数的名字必须与类名相同;
–构造函数没有返回类型—包括void;
–在创建对象时,构造函数才被调用,它的作用是初始化对象。不能被显式调用。

      一个常见的错误是在构造函数前放置一个void。例如:
      void Circle() {......}  //错误,不可以在构造函数前面加任何东西!

    默认构造函数 ( DefaultConstructor )

    若在类声明中没有显式地声明构造函数,则编译器会自动提供一个不带参数、函数体为空(即不做任何事情)的 默认构造函数 

        <类名>::<默认构造函数名> ( ) 

       {

       }


      此时,在程序中创建一个对象时,编译器按默认构造函数来初始化该对象。
      若程序中有自定义的构造函数,编译器就不会再生成(或不再使用)默认构造函数,此时必须使用自定义的构造函数创建对象。

    重载构造函数

    可根据构造函数的形式创建多个不同的对象。


    自定义构造函数

    构造函数可以重载,因此可显式调用自定义构造函数,此时系统将不再提供默认的无参构造函数。可带默认的参数值。

      Date::Date() //无参

      {

          year = 1900;

          month = 1;

          day = 1;

      }


      Date::Date( int y, int m, int d ) //自定义构造函数,带三个参数

      {

             year = y;

             month = m;

             day = d;

      }

      注意:若既有默认参数又有重载的构造函数时,可能出现二义 ( 歧义 ) 性。


      使用不带参数的构造函数创建对象时,对象的创建形式为:类名对象名或: 类名对象名 类名();

      注意:Circle a();  //错误 : 变成了声明了一个函数名为a,返回值为 Circle 类的对象。

      使用带参数的构造函数创建对象时,对象的创建形式为:类名 对象名初始化参数表 );  

      或: 类名 对象名 类名初始化参数表 ); 


   带默认参数的构造函数

   可以使用带默认参数的构造函数 如: Circle( double = 1 );


    注意:创建对象时必须考虑构造函数的形式,若程序中没有定义任何形式的构造函数,系统自动生成默认的无参构造函数。

    若程序中定义了构造函数,则编译器就不再提供默认的无参构造函数,必须使用自定义的构造函数创建对象,否则出错误。

    若要使用多种形式的构造函数创建对象,则必须:
    重载构造函数,即在类定义中增加无参和有参构造函数的定义。或者定义带默认参数的构造函数。

    构造函数的另一种用法:构造函数初始化列表

    构造函数主要用来对类的数据成员进行初始化,常常将构造函数的参数值传送给数据成员,可将构造函数定义为 :

    Date::Date(int y,int m,int d) : year(y),month(m),day(d)

    {  

    }


一个类的对象是另外一个类的数据成员的情况

可以简单理解成:类成员的定义可以相互嵌套定义,一个类的成员可以用另一个类进行定义声明。

如果一个类的对象是另外一类的数据成员,那么在创建对象的时候系统将自动调用那个类的构造函数。 



       介绍完了构造函数之后呢,我们再来看看它的 “兄弟” 折构函数吧~


  析构函数的定义

  析构函数也是特殊的类成员函数,它没有返回类型,没有参数,不能随意调用,也没有重载,只有在类对象的生命期结束的时候,由系统自动调用。 
  析构函数与构造函数最主要大不同就是在于调用期不同,构造函数可以有参数可以重载!

       析构函数名也应与类名相同,只是在函数名前面加一个位取反符~,例如~stud( ),以区别于构造函数

       它不能带任何参数,也没有返回值(包括void类型)。一个类里只能有一个析构函数,不能重载

       如果用户没有编写析构函数,编译系统会自动生成一个缺省的析构函数(即使自定义了析构函数,编译器也总是会为我们合成一个析构函数,并且如果自定义了析构函数,编译器在执行时会先调用自定义的析构函数再调用合成的析构函数,它也不进行任何操作。所以许多简单的类中没有用显示的析构函数。



       学习完这两个函数之后,我们再来看看对象吧~


    对象数组

     对象数组:一个数组中的每个数组元素都为同一类的对象。
     对象数组的声明根据构造函数的不同,有两种形式:
     若没有用户自定义的构造函数,使用默认构造函数;若有用户定义的不带参数或带默认参数的构造函数,则定义数组时可不进行 初始化,其形式为:类名 数组名[常量表达式];

     若只有用户自定义的有参构造函数,则必须在创建对象数组时使用构造函数进行初始化,其形式为:

     类名数组名[常量表达式]={类名(参数表),,类名(参数表)};


    创建对象数组

     常量表达式表示 数组的大小,创建时,系统会创建数组中的每个对象元素,并调用相应的构造函数去初始化每个数组元素。

     Circlec[3];                                                    –使用无参构造函数初始化数组中的元素,此时各个元素中的radius成员值均为1.

     Circlec[3] = {Circle(1),Circle(2),Circle(3)};   –使用有参构造函数初始化对象元素


     当构造函数中只有一个参数或提供了默认参数时也可写为 Circle c[3] = {1,2,3};
     访问数组元素对象的各公有成员:double t1 = c[1].getRadius();

    对象指针

      创建对象时,系统会为该对象分配相应的存储空间存放其数据成员,其起始地址就是对象的地址即指针。
      对象指针:指向对象的指针。

      创建形式:类名 * 对象名;

      Circle   cir, *p = &cir; ( & 表示引用)


      创建对象指针时并不调用构造函数,只是为指针变量分配用于存放地址的空间,并没有创建对象。
      对象指针对对象成员访问


    在堆中创建动态对象

      用new为对象申请空间时需调用构造函数,此时创建了一个对象。如:
      –Circle *p1= new Circle; //调用无参的构造函数
      –Circle *p2=new Circle(2.5); //调用有参的构造函数
      –Circle *p3= new Circle [3];
      –此时必须使用无参数的构造函数,否则不能动态创建!!

      用delete命令为对象删除空间
      –delete p1;
      –delete []p3;  //[]不可省略,否则可能出现错误
      –此时程序会自动调用析构函数。


      学习完这些,我们再来看看内联函数吧~

      内联函数
      内联函数:指在类声明内定义的函数,类外定义的函数缺省情况下都是非内联函数。
      对于内联成员函数,编译时在所有调用该函数的地方将装入实际的函数代码。

    成员函数的实现放在类声明内,此时默认为内联函数

      在类声明外定义的函数缺省情况下都是非内联函数,可用关键字inline强制定义为内联函数



      学习完这些之后,相信各位对函数有所了解了吧~
      今天太累啦,实例下次给出咯~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值