(三)C++构造函数

一、从上一章class声明中的补充

        说设计一个 class 要有一个声明,其实也有一个模板的概念。其中在 class body 中,有些函数在 class body 中直接定义,也有一些在 body 之外定义也没有问题

二、inline(内连)函数

        这里提到一个inline的概念,那么当函数在 class 的本体里面这样定义,就形成了一种 inline ,在外部定义就不会产生 inline 。

        inline 类似于宏,在C中的概念,是一种特性。我们说Function写成inline最好,但是有些Functions即使写成inline,编译器有些也不以为是inline。如果Functions太复杂,就无法认为inline ,  这是由编译器来决定的。

1-  {    }
2-  complex& operator += (const complex&);
3-
4-  double real() const {return re ; }
5-  double imag() const {return im ; }

        在上述代码中 real()与imag()就属于inline的方式,但是具体结果是否为inline,是由编译器决定。函数我们说1、4、5这样的,函数在class中定义完成,那么就成为了inline的侯选项,但注意此时还不是inline。

        Tips:2中在下面并没有定义,在外部,下方就会看到。

三、access level(访问级别)

        在class body中我们可以区分为几大段,用关键字来区分,那么这几个块就是访问级别。如下面这两种(上述代码中):

public:

private:

        pbulic:公开,外部可以看到(Functions分两种,内部使用和外部使用,内部使用也可以放在private:中)

        private:私有,只在class中能够看到。(Data数据部分,应该封装起来)

        其实有第三种,protected:(保护的),这里不提到。

        我们说这些段落可以任意交错,都可以的。那么下面是正确的使用方法:

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

        其中 1- 就是创建一个对象,调用其构造函数。下面的cout 就是利用real()与imag()函数输出实部和虚部。

        下面的错误在于,创建的c1对象我们直接cout它的re(实部)和im(虚部),那么在(二)C++头文件与类的声明中的代码可以看到,re(实部)im(虚部)实际上是在private:中,我们上面说这个private:中放的是数据。

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

        我们说数据,要在同类中进行处理,一个读一个取,利用functions,不能直接在外部对Data进行取值。

四、constructor(ctor,构造函数)

        我们说当你创建一个对象,一个东西,constructor(构造函数)会被调用起来

{
    complex c1(2,1);
    complex c2;
    complex& p = new complex(4);
    ……
}

        这里就是创建一个数c1,其 re 值为2,im 值为1。创建一个c2,没有参数,类似于数学0+0i。第三种动态创建一个复数,得到了一个ptr(指针)。

1-  class complex
2-  {
3-  public:
4-      complex (double r=0,double i=0 )
5-          : re(r),im(i)
6-      {   }
7-  }

         4- 中的函数名称 complex()一定要跟上面的class complex这个类相同,才叫做构造函数。

对于函数complex()中,可以有参数,这里复数设置就是实部与虚部两个参数,这些参数是可以有值的,叫做 default argument(默认实参)。

        那么我们说在创建对象时,像 c1 指定参数的,就使用指定参数,像 c2 未使用指定参数的就用default argument(默认实参)。这个特性并不是构造函数的特性。

        构造函数还有另一种特性,没有返回类型。因为构造函数是用来创建对象,来创建class中complex类的,所以不必写出。

        里面具体要做什么,是自己来设计的。这里就是将r 放到 re 中,i 放到 im中,这个动作是在 6- 这个大括号中利用赋值的写法来完成的。但是我们要采用更好的写法,利用构造函数特别的语法(5-),叫做initialization list(初值列,初始列)。当然4-与5- 也可以写成一行。实际上同 6-{}中是一样的意义。

        简单理解:一个变量,东西,数值的设定有两个阶段,初始化+赋值。初始化为 5-,赋值为6-,忽略5-就是忽略了初始化这个阶段。

complex {double r = 0,double i = 0}
{re = r ;im = i;}

        上述就是将assignments(赋值)这个操作放到了6-中 忽略了5- 。 

        对应构造函数中还有一个析构函数,这里不提到。上述这种class complex 就是说过的不带指针的,类中大部分不用到析构函数。

五、ctor(构造函数)可以有很多个-overloading(重载)

        现实中我们设计某个类,等待外界创建命令,创建命令格式会有多种想法,那么我们这里就将相同函数名称,但有多个构造函数,就称为overloading(重载)

1-  {    }
2-  complex& operator += (const complex&);
3-
4-1  double real() const {return re ; }
4-2  void real(double r) { re = r;}
5-  double imag() const {return im ; }

        4-1与4-2就是典型的 overloading ,那么在编译器中实际中的名称不同,可能是这一种:

?real@Complex@@QBENXZ
?real@Complex@QAENABN@Z

        刚刚说构造函数常常会发生 overloading 的现象,那么我们说这里进行:

1-  class complex
2-  {
3-  public:
4-1      complex (double r=0,double i=0 )
5-          : re(r),im(i)
6-      {   }
4-2      complex () : re(0),im(0) {   }
7-  }

        这里我们说4-1 与 4-2 发生了overloadding,但实际上这是一种错误,因为在4-1中有了默认参数。例如:

{
    complex c1;
    complex c2();
}

        这里创建两个c1与c2,都没有参数,那么编译器并不知道取哪一个complex()用来处理你创建的对象,会发生冲突。


下一章:(四)参数传递与返回值

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值