《c++入门经典》笔记9

《c++入门经典》笔记9

第九章 高级类

9.1 const成员函数

如果使用关键字const将成员函数声明为常量函数(常函数),则表明它不会修改任何类成员的值。要将函数声明为常量函数,可在括号后面添加关键字const:

void displayPage() const;

如果将函数声明为常函数,但其实现修改了成员,编译器就会报错。

对于那些不用来修改类成员的函数,应尽可能将其声明为常函数,这是一种良好的编程习惯。这样可让编译器发现您对成员变量的无意间修改,避免在运行阶段出现这些错误。

9.2接口和实现

9.3组织类声明和函数定义

在c++的源代码中,类的定义和实现通常是分开的。您在类中声明的每个函数都必须有定义。与常规函数一样,类函数也包含函数头与函数体。

定义必须放在编译器能够找到的文件中,大多数c++编译器都要求这种文件的扩展名为.cpp

虽然可以将声明放在源代码文件中,但是大多数程序员采取的做法是,将声明放在头文件中,其文件名与源代码文件相同,但扩展名为.hpp(或是不那么常见的.h或.hp)

因此,如果您将Tricycle类的声明放在文件Tricycle.hpp中,那么类函数的定义位于文件Tricycle.cpp中。通过使用预处理编译指令,可在.cpp文件中包含头文件。

#include "Tricycle.hpp"

将他们分开的原因是,类的客户不关心实现细节,他们需要知道的信息都包含在头文件中。

9.4内联实现

可将常规函数声明为内联,同样,也可将成员函数声明为内联的,为此,需要在返回类型前面指定关键字inline,如下所示:

inline int Tricycle::getSpeed()
{
 return speed;
}

也可将函数定义放在类声明中(也就是写在里面),这样函数将自动变成内联的,如下所示:

class Tricycle
{
public:
 int getSpeed() const 
 {
     return speed;
 }
 void setSpeed(int newSpeed);
};

程序清单9.1与9.2实现了Tricycle类的声明与实现的分离:

程序清单9.1 Tricycle.hpp

#include <iostream>

class Tricycle
{
public:
    Tricycle(int initialAge);
    ~Tricycle();
    int getSpeed() const { return speed; }
    void setSpeed(int speed);
    void pedal()
    {
        setSpeed(speed + 1);
        std::cout << "\nPedaling;tricycle speed " << speed << " mph\n";
    }
    void brake()
    {
        setSpeed(speed - 1);
        std::cout << "\nBraking;tricycle speed " << speed << " mph\n";
    }

private:
    int speed;
};

程序清单9.2 Tricycle.cpp

#include "Tricycle.hpp"

Tricycle::Tricycle(int initialAge)
{
    setSpeed(initialAge);
}
Tricycle::~Tricycle()
{
    std::cout << "Destructed\n";
}
void Tricycle::setSpeed(int newSpeed)
{
    if (newSpeed >= 0)
    {
        speed = newSpeed;
    }
}

int main()
{
    Tricycle wichita(5);
    wichita.pedal();
    wichita.pedal();
    wichita.brake();
    wichita.brake();
    wichita.brake();
    return 0;
}

可以看到运行效果与笔记8 程序清单8.2是一样的。

9.5将其他类用作成员数据的类

创建复杂类时,经常将简单类作为其成员

程序清单9.3与9.4为例:(其实书上给的这个例子里面太多的初始化方法,俺表示无语)

程序清单9.3 Rectangle.hpp

#include <iostream>

class Point
{
public:
    void setX(int newX) { x = newX; }
    void setY(int newY) { y = newY; }
    int getX() const { return x; }
    int getY() const { return y; }

private:
    int x;
    int y;
};

class Rectangle
{
public:
Rectangle(int newTop,int newLeft,int newBottom,int newRight);
~Rectangle(){std::cout << "Destructed\n";}

int getTop() const {return top;}
int getLeft() const {return left;}
int getBottom() const {return bottom;}
int getRight() const {return right;}

Point getUpperLeft() const {return upperLeft;}
Point getLowerLeft() const {return lowerLeft;}
Point getUpperRight() const {return upperRight;}
Point getLowerRight() const {return lowerRight;}

void setUpperLeft(Point location);
void setLowerLeft(Point location);
void setUpperRight(Point location);
void setLowerRight(Point location);

void setTop(int newTop);
void setLeft(int newLeft);
void setBottom(int newBottom);
void setRight(int newRight);

int getArea() const;

private:
Point upperLeft;
Point upperRight;
Point lowerLeft;
Point lowerRight;
int top;
int left;
int bottom;
int right;
};

程序清单9.4 Rectangle.cpp

#include "Rectangle.hpp"

Rectangle::Rectangle(int newTop,int newLeft,int newBottom,int newRight)
{
    top=newTop;
    left=newLeft;
    bottom=newBottom;
    right=newRight;

    upperLeft.setX(left);
    upperLeft.setY(top);

    upperRight.setX(right);
    upperRight.setY(top);

    lowerLeft.setX(left);
    lowerLeft.setY(bottom);

    lowerRight.setX(right);
    lowerRight.setY(bottom);
}

void Rectangle::setUpperLeft(Point location)
{
    upperLeft = location;
    upperRight.setY(location.getY());
    lowerLeft.setX(location.getX());
    top = location.getY();
    left = location.getX();
}

void Rectangle::setLowerLeft(Point location)
{
    lowerLeft=location;
    lowerRight.setY(location.getY());
    upperLeft.setX(location.getX());
    bottom = location.getY();
    left = location.getX();
}

void Rectangle::setLowerRight(Point location)
{
    lowerRight=location;
    lowerLeft.setY(location.getY());
    upperRight.setX(location.getX());
    bottom = location.getY();
    right = location.getX();
}

void Rectangle::setUpperRight(Point location)
{
    upperRight = location;
    upperLeft.setY(location.getY());
    lowerRight.setX(location.getX());
    top = location.getY();
    right = location.getX();
}

void Rectangle::setTop(int newTop)
{
    top = newTop;
    upperLeft.setY(top);
    upperRight.setY(top);
}

void Rectangle::setLeft(int newLeft)
{
    left = newLeft;
    upperLeft.setX(left);
    lowerLeft.setX(left);
}

void Rectangle::setBottom(int newBottom)
{
    bottom = newBottom;
    lowerLeft.setY(bottom);
    lowerRight.setY(bottom);
}

void Rectangle::setRight(int newRight)
{
    right=newRight;
    upperRight.setX(right);
    lowerRight.setX(right);
}

int Rectangle::getArea() const
{
    int width = right - left;
    int height = top - bottom;
    return (width*height);
}

int main()
{
    Rectangle myRectangle(100,20,50,80);
    int area = myRectangle.getArea();
    std::cout<<"Area: "<<area<<std::endl;
    std::cout<<"Upper Left X Coordinate: ";
    std::cout<<myRectangle.getUpperLeft().getX()<<std::endl;
}

posted @ 2020-07-14 20:29  小立哥  阅读(147)  评论(0编辑  收藏  举报