zoukankan      html  css  js  c++  java
  • C++再修(一)————通过一个头文件,来讲解整个程序的部分概念

    这个是候捷版本的C++面向对象高级开发的课程,感觉不错,记下来

    头文件的写法:(防卫式的声明)

    头文件有一种非常正规的写法,一定要学习起来:

    #ifndef _COMPLEX_
    #define _COMPLEX_
              .
              .
              .
              .
              .
    #endif

    一个头文件先这么写(如上),为什么要写这个东西呢?因为有很多程序,要用到你这个头文件,或者你自己也可能用到,如果有很多头文件,用户在调用(include)的时候,会出现到底先调用那个头文件的问题,头文件很多的话,会很难排,所以,这种防卫式的声明,非常管用。大致原理是:但机器执行的时候,一读到第一行代码告诉编译器说:一进来,如果不曾经定义过“_COMPLEX_”这个东西,那么就把它定义出来,然后就继续执行下面的内容,所以,当程序第一此调用(include)这个头文件的话,很容易就被定义好了,在同一个函数里面,第二次再(include)的时候,因为“_COMPLEX_”已经被定义好了,就不会再进来了,下面的代码也就不会再被执行了,这样就可以避免头文件被重复引入。

     

    Header(头文件)的布局:

    那么下面就开始写中间的内容部分,先写第一部分:

    class的声明(declaration):

    任何一个class一定有一个“头”(class head),这里面你就需要去设计,我的复数应该具备什么样的数据,我的应该准备什么样的函数,才能够满足使用复数的人的需求,比如说,大家都知道数学里面有个共轭复数,那我就应该在这里写一个共轭复数这样的函数出来。那结果就是这样

    class complex  /*............................<-class head,“complex”也是类的名称*/
    
    /*................................class body如下*/
    { 
    public:
        complex  (double r = 0, double i = 0)
           :    re  (r),  im  (i)
       {  }
        complex&  opeartor  +=  {const complex&};
        double  real () const { return re;}
        double  imag () const { return im;} 
    private:
       double re, im;/*复数里面有实部和虚部,那我就人为的来定义一下*/ 
    
       friend complex& __doapl (complex*, const complex&)
    }; 

     在函数当中的用法为:

    {
        complex  c1(2,1);
        complex  c2;
        . . .
    }

    inline函数:最好将大部分函数都写成inline的形式,上例中“{ return re; }”“{ return im;}”构成了inline函数,函数若在class body内定义完成,便自动成为inline函数,如果在外头定义,就不是inline函数了。但是,要注意的是,如果函数太过于复杂,就没有办法inline了。比如说,就这两个函数,我们设计成inline函数,但具体是不是按inline来编译,那就是编译器的事情了。

    如果是在非class body下定义完成的inline函数,举例如下:

    inline double
    imag(const complex&  x)
    {
        return  x.imag  () ;
    }

    在一个class body中,很明显可以区分为几大段,用什么来区分呢?就是“public”(公开的,被外界所看的到的)和“private”(只有我class里面才可以看得到)。那什么东西才可以放到“private”里面呢?当然是数据的部分,因为我们需要的数据是封装起来的,不要被外界任意看到。那函数部分呢?函数也分两种,一种给外界用的,一种来处理自己私人的事情,在这个例子里面,大部分函数都是要被外界所使用的,所以,所有函数我们都放在"public"里面。这些段落是可以交错的,想到一段写“public”,再想到一段写“private”无先后顺序,或只能写两段。

    那这有什么影响呢?

    举个例子:

    {
        complex  c1(2,1);
        cout  <<  c1.re;
        cout  <<  c1.im;
    }

    这样写就是错的,因为“re”和“im”定义在“private”里面,是不会被读取出来的。

    而这样写:

    {
        complex  c1{2,1};
        cout  <<  c1.real();
        cout  <<  c1.imag();
    }

    是可以的,因为调用的是"public"里面的“real”和“imag”函数。

    最后总结一下,我们把“public”“private”他们所形成的这个区域,称为:“access level ”访问级别。

    如果你写的函数打算被外界调用,那你就放在“public”里面,如果你写的函数,只打算在内部被运用,没打算被外界调用,那你就放在“private”

    在C++里面,如果你想创建一个东西(就是对象),有一个函数会自动被调用起来,不需要人工调用,自动起来。这就叫做构造函数,比如,下面这个例子:

    {
        complex c1(2,1);
        complex c2;
        complex * p = new complex(4);
        . . .
    }

    这三个都在创建对象,创建对象的话,一定有一个函数在里面。

           这种构造函数的写法很独特,它的函数名称,一定要跟类的函数名称相同,才能够叫做构造函数,并且,它可以用有参数,在class body 里面,complex头文件定义部分。自然想到实部和虚部两个部分来定义。

      complex  (double r = 0, double i = 0)
           :    re  (r),  im  (i)/*这行是初始化,只有构造函数才有,表示把r分给re,把i分给im*/
       {  }

    其中“r=0”和“i=0”都是默认实参(default argument)。就像上面的那个c1有指明参数,那就是用它指明的,c2没有指明的参数,那就用class body 里面定义好的默认实参好了

     充分利用每个函数的特点,是判断编写是否大气的标志,上面就是大气的一个典范!

     构造函数可以有很多个-overloading(重载),比如说你设计一个类,等待外界来创建一个对象,创建对象的时候要怎么创建?假设你有三种设计思路,那你就写出三个构造函数,C里面是不允许这样做的,但C++是允许的。相同函数名称,却不止一个,这个就叫做overloading

    举个例子:

    void real(double r)   ( re=r;)

    这样定义也是可以的,虽然,会跟class body 里面的real冲突,它们机器码不一样。

    但如果是这种情况下:

    complex  (double r = 0, double i = 0)
           :    re  (r),  im  (i)
       {  }
    complex   ()    :   re(0) , im(0)  {}

    因为重名,会出现冲突。

    函数重载,一般多发生在构造函数里面。

    * class template(模板)

    在上面的class中,实部和虚部是人工定义为double值,那我如果要设计另外一个复数,它里面的类型是浮点数(float),或者是整数,怎么办?可上面已经写死了,不能动了,那就只好再把原来的程序原样敲一遍,只到定义实部和虚部的部分,改一下,这样写太麻烦了,于是,C++的设计者,就发明了针对类似这种情况的东西————class template(模板),写成:把实部和虚部的位置不要先写死,我想要以后用的时候,我再指定 

    template<typename T>/*提前告诉编译器,T是一个type*/
    class complex
    { 
    public:
        complex  (double r = 0, double i = 0)
           :    re  (r),  im  (i)
       {  }
        complex&  opeartor  +=  {const complex&};
        double  real    ()   const  {  retrun  re;  }
        double  imag   ()   const  { return  im;}
    private:
        T  re,  im;/*T的意思可以理解成告诉编译器:我现在是什么类型,我还没有决定呦!*/
    
        friend  complex& __doapl  (complex*,  const  complex&)
    };

    在函数当中的用法为:

    {
        complex<double>  c1(2.5,1.5);
        complex<int>  c2(2, 6);
        . . .
    }
    相信坚持的力量!
  • 相关阅读:
    (六)目标文件目录探测
    (五)物理路径探测
    (四)目标后台的探测
    小妙招
    MFC的一些常用操作
    UNICODE,GBK,UTF-8区别
    c++编程的字符集及其转换
    windows消息的循环机制
    c++ mfc和win32项目
    c++ 一些注意事项
  • 原文地址:https://www.cnblogs.com/duijinglianxinduijingxiuxing/p/7581898.html
Copyright © 2011-2022 走看看