HOUR 9 Moving into Advanced Classes
const Member Functions
如果声明成员函数为const类型,那就意味着该函数没有权限修改类中的任何值,const声明在括号后面:
void displayPage() const
如果想取变量的值,就可以使用const成员函数了,避免了不小心修改了变量。const成员函数如果编程时修改了成员变量的值,那么编译器会报错。应当尽可能多的使用const成员函数。
例如:
void setSpeed(int newSpeed);/用来设置速度,所以不可以是const int getSpeed() const; //用来获取速度,可以加上const限定,避免误改
Organizing Class Declarations adn Function Definitions
正规的写class都是类的声明和类的定义分开,声明部分在hpp头文件中,定义在cpp中,两个文件同名即可,因为类用户不关心类具体如何实现的,客户只关注类中包含哪些数据、action等,而要知道这些,客户只需要看你的头文件就可以了。
inline implementation
C++的类中的members function想要实现内联函数,有两种方法
- 按照普通的inline定义方法,在函数前面写个inline
- 在类声明的时候,直接将函数体写到类内部,编译器自动内联
Classes with other Classes as Member Data一种常用的创建复杂类的方法是,在类内声明其他简单的类作为其成员。
例如,你可能已经有了Wheel, Motor, Transmission 等类,当你定义一个Car 类的时候,从这样的角度去定义(has-a 关系):
一辆车有一组轮子、有一个motor, 有一个变速箱。
考虑下面一个例子,来理解这一概念:
一个Rectangle类,由四条线组成,每条线由两个点定义,一个点由(x,y)坐标表示,具体看下面的完整示例,so far so good.
#ifndef RECTANGLE_H #define RECTANGLE_H #include <iostream> class Point { //no constructor, use default public: void setX(int newX) { x = newX;} void setY(int newY) {y = newY;} int getX() const {return x;} int getY() const {return y;} int test; private: int x; int y; }; class Rectangle { public: Rectangle(int newTop, int newLeft, int newBottom, int newRight); ~Rectangle() {}; 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 getUpperRight() const { return upperRight;} Point getBottomLeft() const {return lowerLeft;} Point getBottomRight() const {return lowerRight;} void setUpperLeft(Point location); void setUpperRight(Point location); void setLowerLeft(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 right; int bottom; }; #endif // RECTANGLE_H
#include "rectangle.h" 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::setUpperRight(Point location) { upperRight = location; upperLeft.setY(location.getY()); lowerRight.setX(location.getX()); top = location.getY(); right = 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::setTop(int newTop) { top = newTop; upperLeft.setY(top); upperRight.setY(top); } void Rectangle::setBottom(int newBottom) { bottom = newBottom; lowerLeft.setY(bottom); lowerRight.setY(bottom); } void Rectangle::setLeft(int newLeft) { left = newLeft; lowerLeft.setX(left); upperLeft.setX(left); } 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); }
#include <QCoreApplication> #include "rectangle.h" #include <iostream> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); Rectangle myRectangle(50, 30, 10, 80); int areaShow = myRectangle.getArea(); std::cout << "The area is " << areaShow << std::endl; Point upperLeft = myRectangle.getUpperLeft(); std::cout << "UpperLeft cordinate is ( " << upperLeft.getX() << "," << upperLeft.getY() << ")\n" ; Rectangle hiRectangle; areaShow = hiRectangle.getArea(); std::cout << "area is " << areaShow << std::endl; return a.exec(); }
Summary
- 使用类可以有效的提高代码重用性,例如word里面的拼写检查,可以直接移植到网页编辑器中,不需要从轮子造
- 类的使用可以让程序更加可靠。面向object让任务分割开来,思维量大大减小,也更容易找出bug
Q&A
Q. 为什么要用const限定部分成员函数
A. 在不允许修改成员变量的函数中,加上const限定可以让编译器帮你界定一些愚蠢的错误,例如
//getSpeed()函数中包含这行 if(speed = 100) cout << "Max Speed Reached\n";
很明显,这里有一个错误,逻辑判断speed == 100?错误的写成赋值了,这样的话变量speed被悄悄的修改了,而且很难发现。如果你当时加上const限定,编译器就识别出来了

浙公网安备 33010602011771号