zoukankan      html  css  js  c++  java
  • c++入门之 再话类

    对于类,其结构并不难,但要理解其设计思想也并不容易,在此,我们可以通过下面的代码进一步理解和使用类:

     1 # ifndef VECTOR_H_
     2 # define VECTOR_H_
     3 # include "iostream"
     4 
     5 namespace VECTOR //注意,这里对这个类定义了名称空间,实际上,在写自己的类时,也应该定义自己的名称空间
     6 {
     7     class Vector
     8     {
     9     public:
    10         enum Mode{RECT,POL};//因为这个量需要用户自己去设定
    11     private:           //注意:私有成员(无论是函数还是变量)只能被类内部成员访问
    12         double x;
    13         double y;
    14         double mag;
    15         double ang;
    16         Mode mode;
    17         
    18         void set_mag();
    19         void set_ang();
    20         void set_x();
    21         void set_y();   //体会将这些函数放在这里的用意!!
    22     public:             //共有成员可以被所有访问!!理解这个意思
    23         Vector();//构造函数
    24         Vector(double n1,double n2,Mode form = RECT);//注意,这里有默认参数
    25         void reset(double n1, double n2, Mode form = RECT);
    26         ~Vector();//析构函数
    27         double xval() const{ return x; }
    28         double yval() const{ return y; }
    29         double magval() const{ return mag; }
    30         double angval() const{ return ang; }
    31         void polar_mode();
    32         void rect_mode();
    33 
    34         Vector operator+(const Vector &b) const;
    35         Vector operator-(const Vector &b) const;
    36         Vector operator-() const;
    37         Vector operator*(double n) const;
    38 
    39         friend Vector operator*(double n, const Vector &a);//注意这里采用了友元函数的做法,应该显示包含所有参数
    40         friend std::ostream & operator<<(std::ostream &os, const Vector & v);//昨天没有思考返回引用是否存在问题???因为局部变量被销毁的问题
    41     };
    42 
    43 }
    44 # endif

    该类定义中:除了备注的一些以外,总结这么几点:

    1 定义了一个类的时候,限定了该类的名称空间通常是一件好事,以免自己的变量和别人的发生了冲突

    2   公有还是私有并无界限之分,完全取决于程序的功能。

    3  我们通常会发现:当定义一个类成员函数时,通常需要:构造函数,析构函数,甚至友元函数

    4  私有成员(无论是变量还是函数)只能被类内部的成员进行访问,而共有成员 可以被其他类甚至其他任何东西访问。究其本质:公有部分 是提供的接口

    下面给出该定义:

      1 # include"cmath"  //从下文的调用方法来看,这里应该是函数库,而不是类库
      2 # include "vector.h"
      3 using std::sqrt;   //注意 std 包含了很多
      4 using std::sin;
      5 using std::cos;
      6 using std::atan;
      7 using std::atan2;
      8 using std::cout;
      9 
     10 namespace VECTOR  //名称空间的意义是很有必要的
     11 {
     12     const double Rad_to_deg = 45.0 / atan(1.0);
     13     void Vector::set_ang()
     14     {
     15         mag = sqrt(x*x + y*y); //求极长
     16     }
     17 
     18     void Vector::set_ang()
     19     {
     20         if (x == 0.0  && y == 0.0)
     21             ang = 0.0;
     22         else
     23             ang = atan2(y, x);//求极角
     24     }
     25 
     26     void Vector::set_x() //这些是私有函数
     27     {                 
     28         x = mag*cos(ang);//私有函数可以访问私有变量表明私有成员也可以相互访问
     29     }
     30 
     31     void Vector::set_y()
     32     {
     33         y = mag*sin(ang);
     34     }
     35 
     36     Vector::Vector()
     37     {
     38         x = y = mag = ang = 0.0;
     39         mode = RECT;
     40     }
     41 
     42     Vector::Vector(double n1, double n2, Mode form)
     43     {
     44         mode  = form;
     45         if (form == RECT)
     46         {
     47             x = n1;
     48             y = n2;
     49             set_mag();//访问了私有成员
     50             set_ang();//体会这里的设计思想
     51         }
     52         else if (form == POL)
     53         {
     54             mag = n1;
     55             ang = n2;
     56             set_x();
     57             set_y();
     58         }
     59         else
     60         {
     61             cout << "Incorrect 3rd argument to Vector()--";
     62             cout << "vector set to 0
    ";
     63             x = y = mag = ang = 0.0;
     64             mode =RECT;
     65         }
     66     }
     67     void Vector::reset(double n1, double n2, Mode form)
     68     {
     69         mode = form;
     70         if (form = RECT)
     71         {
     72             x = n1;
     73             y = n2;
     74             set_mag();
     75             set_ang();
     76         }
     77         else if (form = POL)
     78         {
     79             mag = n1;
     80             ang= n2;
     81             set_x();
     82             set_y();
     83         }
     84         else
     85         {
     86             cout << "Incorrect 3rd argument to Vector()--";
     87             cout << "vector set to 0
    ";
     88             x = y = mag = ang = 0.0;
     89             mode = RECT;
     90         }
     91     }
     92     Vector::~Vector()//
     93     {
     94 
     95     }
     96 
     97     void Vector::polar_mode()
     98     {
     99         mode = POL;
    100     }
    101 
    102     void Vector::rect_mode()
    103     {
    104         mode = RECT;
    105     }
    106 
    107     Vector Vector::operator+(const Vector &b) const
    108     {
    109         return Vector(x + b.x, y + b.y);
    110     }
    111 
    112     Vector Vector::operator-(const Vector &b) const
    113     {
    114         return Vector(x - b.x, y - b.y);
    115     }
    116 
    117     Vector Vector::operator-() const
    118     {
    119         return Vector(-x, -y);
    120     }
    121 
            Vector Vector::operator*(double n) const
            {
    return(n*x,x*y)
    }

    122 Vector operator*(double n, const Vector & a) 123 { 124 return a*n; //注意,虽然这里进行了返回,但并没有结束,而是继续调用了成员函数, 125 } 126 127 std::ostream & operator<<(std::ostream & os, const Vector & v) 128 { 129 if (v.mode == Vector::RECT) 130 os << "(x,y) = (" << v.x << "," << v.y << ")"; 131 else if (v.mode == Vector::POL) 132 { 133 os << "(m,a) = (" << v.mag << "," << v.ang + Rad_to_deg << ")"; 134 } 135 else 136 os << "Vector object mode is invalid"; 137 } 138 }

    1.  我们注意107行和112行的代码:本质上,进行了加法和减法之后,得到的是一个新的类对象,但由于这个类对象不止一种表示形式(直角坐标和极坐标),这里巧妙的利用了 返回构造函数的执行。这告诉我们:构造函数并不仅仅用于初始化,构造函数的本意:构造新的对象,一定要认识这一本质特征和思想。

    2  我们注意124行的代码:return a*n; 本质上,对象乘以一个数无法实现,但这里,其实,并没有返回,而是回去重新调用了上面的*。

    3 注意:129行和131行:if (v.mode == Vector::RECT)。为何要加Vector::RECT而不是RECT,这是因为:

    友元函数虽然在public中,但友元函数并不在类作用域中!!! 这对于所有友元函数都成立!!!

  • 相关阅读:
    ansible become与sudo
    GTID 复制、主从不一致跳过操作、快速切换master
    percona toolkit 更新至一致性检查
    oracle ldap (ODEE ODCC)复制概要
    zabbix api 批量添加主机(python3 requests)
    grafana 5.0+ templating变化
    redis sentinel 客户端
    centos7 变更默认mariadb 记录
    python3 float 计算
    企业微信开发记录
  • 原文地址:https://www.cnblogs.com/shaonianpi/p/9943993.html
Copyright © 2011-2022 走看看