《C++编程风格》第三章: 不必要的继承

原书抄录

一个C++类有着两个重要的方面:用于描述类行为的公有接口,以及行为的私有实现
大多数继承所采用的都是公有继承的形式:派生类同时继承了基类的借口和实现。
在私有基类中,派生类继承了所有的实现,但没有继承任何接口。
而在继承公有的抽象基类时,派生类继承了所有的接口,但所继承的实现可能是不完整的或者是不存在的。


规则总结:

  • 我们要找出简单的抽象
  • 我们要识别出对实现的继承;可以使用私有基类或者(更好的方法是)使用成员对象
  • 我们应该考虑使用默认参数的形式来代替函数重载的形式。

章后习题:

这里写图片描述

解答:
我创建一个基类Point,两个派生类Circle和Line。
其中, Circle通过私有继承的方式获取Point的服务, 而因为要使用两个point对象,因此Line私有成员的方式获取服务。

代码:

#include <iostream>
#include <cmath>
using namespace std;

class Point
{
public:
    Point(int x_, int y_):
        x(x_), y(y_)
    {}

    void SetLoc(int x_, int y_)
    {
        x = x_, y = y_;
    }

    int GetX() const
    {
        return x;
    }

    int GetY() const
    {
        return y;
    }

private:
    int x, y;
};

class Circle: private Point
{
public:
    Circle(int x_, int y_, int r_):
        Point(x_, y_), r(r_)
    {}

    void Set(int x_, int y_, int r_)
    {
        Point::SetLoc(x_, y_);
        r = r_;
    }

    void SetLoc(int x_, int y_)
    {
        Point::SetLoc(x_, y_);
    }

    void SetRadius(int r_)
    {
        r = r_;
    }

    Point GetLoc() const
    {
        return Point(Point::GetX(), Point::GetY());
    }

    int GetRadius() const
    {
        return r;
    }

    double Area() const
    {
        return 3.14*r*r;
    }

    double Length() const
    {
        return 2 * 3.14 * r;
    }

private:
    int r;
};

class Line
{
public:
    Line(int x1, int y1, int x2, int y2):
        sp(x1, y1), ep(x2, y2)
    {}

    void SetLoc(int x1, int y1, int x2, int y2)
    {
        sp.SetLoc(x1, y1);
        ep.SetLoc(x2, y2);
    }

    void SetStart(int x, int y)
    {
        sp.SetLoc(x, y);
    }

    void SetEnd(int x, int y)
    {
        ep.SetLoc(x, y);
    }

    Point GetStart() const
    {
        return sp;
    }

    Point GetEnd() const
    {
        return ep;
    }

    double Length() const
    {
        return sqrt( pow(sp.GetX() - ep.GetX(), 2) + pow(sp.GetY() - ep.GetY(), 2) );
    }   

private:
    Point sp, ep;
};

int main()
{
    Circle c(0, 0, 1);
    Point p = c.GetLoc();

    cout << "Circle Loc: (" << p.GetX() << ", " << p.GetY() << ")" << endl;
    cout << "Circle Area: " << c.Area() << endl;
    cout << "Circle Length: " << c.Length() << endl;

    Line l(-1, 2, 3, 5);
    Point sp = l.GetStart(), ep = l.GetEnd();
    cout << "Line Start Loc: (" << sp.GetX() << ", " << sp.GetY() << ")" << endl;
    cout << "Line End Loc: (" << ep.GetX() << ", " << ep.GetY() << ")" << endl;
    cout << "Line Length: " << l.Length() << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值