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\n";
 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\n";
 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中,但友元函数并不在类作用域中!!! 这对于所有友元函数都成立!!!

猜你喜欢

转载自www.cnblogs.com/shaonianpi/p/9943993.html