zoukankan      html  css  js  c++  java
  • [c++] 面向对象课程(一)-- 不带指针类的设计

    Object Based(基于对象)

    • class without pointer menbers
    • class with pointer menbers

    Object Oriented(面向对象)

    • Classes之间的关系
      • 继承(inheritance)
      • 复合(composition)
      • 委托(delegation) 

    complex类:

    complex.h

      1 #ifndef __MYCOMPLEX__
      2 #define __MYCOMPLEX__
      3 
      4 class complex; 
      5 complex&
      6   __doapl (complex* ths, const complex& r);
      7 complex&
      8   __doami (complex* ths, const complex& r);
      9 complex&
     10   __doaml (complex* ths, const complex& r);
     11 
     12 
     13 class complex
     14 {
     15 public:
     16   complex (double r = 0, double i = 0): re (r), im (i) { }
     17   complex& operator += (const complex&);
     18   complex& operator -= (const complex&);
     19   complex& operator *= (const complex&);
     20   complex& operator /= (const complex&);
     21   double real () const { return re; }
     22   double imag () const { return im; }
     23 private:
     24   double re, im;
     25 
     26   friend complex& __doapl (complex *, const complex&);
     27   friend complex& __doami (complex *, const complex&);
     28   friend complex& __doaml (complex *, const complex&);
     29 };
     30 
     31 
     32 inline complex&
     33 __doapl (complex* ths, const complex& r)
     34 {
     35   ths->re += r.re;
     36   ths->im += r.im;
     37   return *ths;
     38 }
     39  
     40 inline complex&
     41 complex::operator += (const complex& r)
     42 {
     43   return __doapl (this, r);
     44 }
     45 
     46 inline complex&
     47 __doami (complex* ths, const complex& r)
     48 {
     49   ths->re -= r.re;
     50   ths->im -= r.im;
     51   return *ths;
     52 }
     53  
     54 inline complex&
     55 complex::operator -= (const complex& r)
     56 {
     57   return __doami (this, r);
     58 }
     59  
     60 inline complex&
     61 __doaml (complex* ths, const complex& r)
     62 {
     63   double f = ths->re * r.re - ths->im * r.im;
     64   ths->im = ths->re * r.im + ths->im * r.re;
     65   ths->re = f;
     66   return *ths;
     67 }
     68 
     69 inline complex&
     70 complex::operator *= (const complex& r)
     71 {
     72   return __doaml (this, r);
     73 }
     74  
     75 inline double
     76 imag (const complex& x)
     77 {
     78   return x.imag ();
     79 }
     80 
     81 inline double
     82 real (const complex& x)
     83 {
     84   return x.real ();
     85 }
     86 
     87 inline complex
     88 operator + (const complex& x, const complex& y)
     89 {
     90   return complex (real (x) + real (y), imag (x) + imag (y));
     91 }
     92 
     93 inline complex
     94 operator + (const complex& x, double y)
     95 {
     96   return complex (real (x) + y, imag (x));
     97 }
     98 
     99 inline complex
    100 operator + (double x, const complex& y)
    101 {
    102   return complex (x + real (y), imag (y));
    103 }
    104 
    105 inline complex
    106 operator - (const complex& x, const complex& y)
    107 {
    108   return complex (real (x) - real (y), imag (x) - imag (y));
    109 }
    110 
    111 inline complex
    112 operator - (const complex& x, double y)
    113 {
    114   return complex (real (x) - y, imag (x));
    115 }
    116 
    117 inline complex
    118 operator - (double x, const complex& y)
    119 {
    120   return complex (x - real (y), - imag (y));
    121 }
    122 
    123 inline complex
    124 operator * (const complex& x, const complex& y)
    125 {
    126   return complex (real (x) * real (y) - imag (x) * imag (y),
    127                real (x) * imag (y) + imag (x) * real (y));
    128 }
    129 
    130 inline complex
    131 operator * (const complex& x, double y)
    132 {
    133   return complex (real (x) * y, imag (x) * y);
    134 }
    135 
    136 inline complex
    137 operator * (double x, const complex& y)
    138 {
    139   return complex (x * real (y), x * imag (y));
    140 }
    141 
    142 complex
    143 operator / (const complex& x, double y)
    144 {
    145   return complex (real (x) / y, imag (x) / y);
    146 }
    147 
    148 inline complex
    149 operator + (const complex& x)
    150 {
    151   return x;
    152 }
    153 
    154 inline complex
    155 operator - (const complex& x)
    156 {
    157   return complex (-real (x), -imag (x));
    158 }
    159 
    160 inline bool
    161 operator == (const complex& x, const complex& y)
    162 {
    163   return real (x) == real (y) && imag (x) == imag (y);
    164 }
    165 
    166 inline bool
    167 operator == (const complex& x, double y)
    168 {
    169   return real (x) == y && imag (x) == 0;
    170 }
    171 
    172 inline bool
    173 operator == (double x, const complex& y)
    174 {
    175   return x == real (y) && imag (y) == 0;
    176 }
    177 
    178 inline bool
    179 operator != (const complex& x, const complex& y)
    180 {
    181   return real (x) != real (y) || imag (x) != imag (y);
    182 }
    183 
    184 inline bool
    185 operator != (const complex& x, double y)
    186 {
    187   return real (x) != y || imag (x) != 0;
    188 }
    189 
    190 inline bool
    191 operator != (double x, const complex& y)
    192 {
    193   return x != real (y) || imag (y) != 0;
    194 }
    195 
    196 #include <cmath>
    197 
    198 inline complex
    199 polar (double r, double t)
    200 {
    201   return complex (r * cos (t), r * sin (t));
    202 }
    203 
    204 inline complex
    205 conj (const complex& x) 
    206 {
    207   return complex (real (x), -imag (x));
    208 }
    209 
    210 inline double
    211 norm (const complex& x)
    212 {
    213   return real (x) * real (x) + imag (x) * imag (x);
    214 }
    215 
    216 #endif   //__MYCOMPLEX__
    View Code

    complex_test.cpp

     1 #include <iostream>
     2 #include "complex.h"
     3 
     4 using namespace std;
     5 
     6 ostream&
     7 operator << (ostream& os, const complex& x)
     8 {
     9   return os << '(' << real (x) << ',' << imag (x) << ')';
    10 }
    11 
    12 int main()
    13 {
    14   complex c1(2, 1);
    15   complex c2(4, 0);
    16 
    17   cout << c1 << endl;
    18   cout << c2 << endl;
    19   
    20   cout << c1+c2 << endl;
    21   cout << c1-c2 << endl;
    22   cout << c1*c2 << endl;
    23   cout << c1 / 2 << endl;
    24   
    25   cout << conj(c1) << endl;
    26   cout << norm(c1) << endl;
    27   cout << polar(10,4) << endl;
    28   
    29   cout << (c1 += c2) << endl;
    30   
    31   cout << (c1 == c2) << endl;
    32   cout << (c1 != c2) << endl;
    33   cout << +c2 << endl;
    34   cout << -c2 << endl;
    35   
    36   cout << (c2 - 2) << endl;
    37   cout << (5 + c2) << endl;
    38   
    39   return 0;
    40 }
    View Code

    头文件

    • 防卫式声明

    类设计

    • 数据放在private

    构造函数

    • initialization list 执行速度比{ }中快
    • 以什么方式创建对象,怎么想的就写几种构造函数(overloading)
    • 同名的函数可以有不止一个,两个real(),一个取得实部,一个设置实部(函数在编译器中的实际名称是函数名+参数名+参数个数)
    • complex(double r = 0, double i = 0):re(r),im(i){...}和complex():re(0),im(0){...}  不能同时存在,编译器无法选择
    • complex c1;和complex c2();  含义相同
    • 通常情况,构造函数是public的,只有一个例外,单例模式(外界只能用自己类中创建的一份实例)

    const member functions(常量成员函数)

    • 对不改变数据的函数,在函数名后加const。如:double real() const { return re; }
    • 不加的话,使用者用const型数据调用该函数时会出错。如:const complex c1(2,1) ; cout<< c1.real() ;
    • const只能修饰输入参数,成员函数省略了this指针,所以const没地方放,只好放在函数体外了
    • 在普通的非 const成员函数中,this的类型是一个指向类类型对象的 const指针,可以改变this所指向的值,但不能改变 this所保存的地址
    • 在 const成员函数中,this的类型是一个指向 const类类型对象的 const指针。既不能改变 this所指向的对象,也不能改变 this所保存的地址

    参数传递 pass by value vs. pass by reference( to const )

    • complex ( double r = 0 ; double i = 0 )  把数据整包传过去,效率较低(此处传一个double和效率和传引用一样,都是4byte)  complex c1(2,1); 
    • complex& operator +=  ( const complex& );   传引用,相当于传指针,尽量采用;若希望传递后变量不更改就加const限制  c2 += c1;
    • ostream& operator << ( ostream& os, const complex& x){...}  第一个参数没有加const,是因为函数体中会改变os的值

    返回值传递 return by value vs. return by reference( to const )

    • double real() const { return re; }  传值
    • complex& operator +=  ( const complex& );  传引用,尽量采用

    friend(友元)

    • 朋友可以来拿钱(数据)
    • 直接拿数据,打破了封装,也可设计为通过函数拿数据
    • friend complex& __doapl ( complex*, const complex& ) ;
    • inline complex& __doapl( complex* ths, const complex& r ) { ths->re += r.re ; ths->im += r.im; return *ths ; }

    相同class的各个objected互为friends

    • int func ( const complex& param ) { return param.re + paream.im ; }
    • c2.func ( c1 ) ;

    class body 外的各种定义

    什么时候可以pass by reference,什么时候可以return by reference

    • inline complex& __doapl( complex* ths, const complex& r ) { ths->re += r.re ; ths->im += r.im; return *ths ; }
    • 两参数相加后,结果放到第一个参数中,第一个参数被改动,第二个不会被改动
    • 这种情况能用return by reference,因为函数结束后第一个参数不会消失
    • 在函数中创建一个地方放结果,则不能用return by reference,因为函数结束后local变量会消失

    操作符重载(成员函数)

    • c2 += c1;
    • inline compex& complex::operator += ( const complex& r){...}
    • 在编译器中的完整形式:inline compex& complex::operator += ( this, const complex& r){...}
    • 编译器在执行时,检查类中定义的运算作用在左值上,c2对应this,c1对应r
    • this为调用者(“谁”调用的),编译器自动把c2的地址传入this
    • 函数嵌套 60-73 便于复用
    • doapl为“do assignment plus”即“做赋值加法”的缩写

    return by reference 语法分析

    • 60声明中返回值为引用,而66中定义为指针:返回object,接收object的引用
    • 传递端无需知道接收端的接收方式(在接收端设计)
    • 返回类型写void有隐患,导致使用者不能连续赋值如,c3 += c2 += c1 ;  
    • 其他如 << 和 >> 也有此问题

     操作符重载(非成员函数)

    • + 写成全局函数,因为会有复数加其他类型数据的情况(一共写了3个+函数)
    • c2 = c1 + c2; c2 = c1 + 5; c2 = 7 + c1;
    • 全局函数,无this指针
    • return by value,因为返回local object
    • 临时变量存储+的结果,之前是把右值加到左值,返回左值
    • typename(); 创建临时对象,没有名字,下一行就没了
    • 正号运算符虽然没改变参数值,但也不能返回&,编译器会报错
    • << 必须写成全局,因为标准库只能识别内置数据类型,无法识别object<<cout
    • cout是一个object,type是ostream
    • 参数ostream前不可加const,因为os在函数中会改变
    • 返回值不是void,便于继续接收右边的输出,如:cout<<c1<<conj(c1)
    • 返回值ostream前不可加const,因为连续输出时返回值会改变
    • 返回值本来就有,不是local的,所以传引用
  • 相关阅读:
    Python 内置函数
    Python OS 文件/目录方法
    python import导入模块
    Python 变量、作用域、闭包
    Python3 迭代器(generate)与生成器(yield) 装饰器(decorator) 上下文管理器(context manager)
    SpringBoot Admin的简单使用
    java学习网址
    idea的破解码
    Jmeter响应内容显示乱码问题的解决办法
    ClickHouse 库引擎
  • 原文地址:https://www.cnblogs.com/cxc1357/p/12273955.html
Copyright © 2011-2022 走看看