现在的位置: 首页 > 综合 > 正文

由中兴一道笔试题想到的

2013年02月13日 ⁄ 综合 ⁄ 共 1999字 ⁄ 字号 评论关闭

c++编程实现:
一个Point类,然后一个Circle类,继承Point类。circle类能够实现求圆的面积,移动圆的位置,改变圆的大小。

 

基于实际应用的考虑:

Circle派生自Point,乍一想圆缩小到最后不就是个点嘛,这个还算合情合理。但是当圆遇到圆心时问题就出现了。

A Circle is not a Point. It is implemented in terms of Points。

Point类的成员变量容易确定,即X坐标和Y坐标,然而Circle类的圆心也是Point,该做何处理?

1)如果Circle以父类的成员变量作为圆心的坐标,显然圆心与圆的关系使用Composition更好。

2)将Point的成员变量设为private,Circle在继承Point的同时,包含一个Point的成员变量表示圆心。但这样还费劲继承干吗,不如直接Composition。

 

实现:

暂且抛开点派生圆的合理性问题,让我们从上面第1种实现出发,看看需要注意哪些内容:

1)  Point类的两个成员变量最好声明为protected,以便Circle在必要时进行修改。

2)  Point类的析构函数定义为虚函数,以防止当Circle对象被Point指针析构时,子类数据没有被析构掉。

3) PI的定义,既然是C++了,最好就不要用C形式的#define,我这里采用的方式是static const成员变量,当然也可以定义一个const全局变量。

4)求圆的面积和改变圆的大小只能在Circle类中实现,因为Point没有这两项需求。

而移动圆的位置,最好实现在Point类中,首先这是Point类本身的需要,而对于Circle类来说,移动圆的位置等同于移动圆心的位置。

5) 出于性能考虑,可以适当将成员变量声明为inline函数,定义在类里面的函数本身就是内联的。出于泛化考虑,可以使用模板类,将X和Y坐标以及半径的数据类型声明为模板参数。

 

 

代码如下:

    1. template <typename T>
    2. class Point
    3. {
    4. public:
    5.     Point()
    6.     { }
    7.     Point(const T& x, const T& y)
    8.         : _x(x)
    9.         , _y(y)
    10.     { }
    11.     Point(const Point<T>& pt)
    12.         : _x(pt._x)
    13.         , _y(pt._y)
    14.     { }
    15.     virtual ~Point()
    16.     { }
    17. public:
    18.     void SetX(const T& x)
    19.     {
    20.         _x = x;
    21.     }
    22.     void SetY(const T& y)
    23.     {
    24.         _y = y;
    25.     }
    26.     T GetX()
    27.     {
    28.         return _x;
    29.     }
    30.     T GetY()
    31.     {
    32.         return _y;
    33.     }
    34.     virtual void SetPosition(const T& x, const T& y)
    35.     {
    36.         _x = x;
    37.         _y = y;
    38.     }
    39. protected:
    40.     T _x;
    41.     T _y;
    42. };
    43. template<typename T, typename U>
    44. class Circle : public Point<T>
    45. {
    46. public:
    47.     Circle() : Point<T>()
    48.     { }
    49.     Circle(const T& x, const T& y, const U& radius)
    50.         : Point<T>(x, y)
    51.         , _radius(radius)
    52.     { }
    53.     Circle(const Circle<T, U>& rcCcl)
    54.         : Point<T> (rcCcl._x,rcCcl._y)
    55.         , _radius(rcCcl._radius)
    56.     { }
    57.     ~Circle()
    58.     { }
    59. public:
    60.     void SetRadius(const U& radius)
    61.     {
    62.         _radius = radius;
    63.     }
    64.     U GetRadius()
    65.     {
    66.         return _radius;
    67.     }
    68.     U GetArea()
    69.     {
    70.         return _pi* _radius * _radius;
    71.     }
    72. private:
    73.     U _radius;
    74.     static const double _pi;
    75. };
    76. template <typename T, typename U>
    77. const double Circle<T,U>::_pi = 3.14159;

抱歉!评论已关闭.