WHCSRL 技术网

C++中的对象和类

1、抽象和类

1.1、C++中的类

一般来说,类规范由两部分组成:

  • 类声明:以数据成员的方式描述数据部分,以成员函数(被称为方法)的方式描述共有接口。
  • 类方法定义:描述如何实现类成员函数。

关键词private和public描述了对类成员的访问控制。使用类对象的程序都可以直接访问共有部分,但只能通过公有成员函数或友元函数来访问对象的私有成员。数据项通常放在私有部分,组成类接口的成员函数放在共有部分。

  1. #ifndef STOCK00_H_
  2. #define STOCK00_H_
  3. #include <string>
  4. class Stock //声明Stock类
  5. {
  6. private:
  7. std::string company;
  8. long shares;
  9. double share_val;
  10. double total_val;
  11. void set_tot() { total_val=shares*share_val; }
  12. public:
  13. void acquire(const std::string& co, long n, double pr);
  14. void buy(long num, double price);
  15. void sell(long num, double price);
  16. void update(double price);
  17. void show();
  18. };

内联方法:定位于类声明中的函数都将自动成为内联函数,因此Stock::set_tot()是一个内联函数。类声明常将短小的成员函数作为内联函数,set_tot()符合这样的要求。也可以在类声明之外定义成员函数,并使其成为内联函数,只需要在实现部分中定义函数时使用inline限定符即可:

  1. inline void Stock::set_tot()
  2. {
  3. total_val=shares*share_val;
  4. }

内联函数的特殊规则要求在每个使用他们的文件中都对其进行定义。确保内联定义对多文件程序中的所有文件都是可用的,最简便的方法是:将内联函数定义放在定义类的头文件中

1.2、类的构造函数和析构函数

C++提供了两种使用构造函数来初始化对象的方式。一种方式是显式地调用构造函数:

Stock food=Stock("World Cabbage", 250, 1.25);

将food对象的company成员设置为字符串“World Cabbage”,将shares成员设置为250.

另一种方式是隐式地调用构造函数:

Stock qarment=Stock("Furry Mason",50,2.5);

1.3、const成员函数

对于函数代码:

const Stock land=Stock{"Kludgehorn Properties"};

land.show();

对于C++来说,编译器将拒绝第二行。因为show()函数的代码无法确保调用的对象不被修改——调用对象和const一样,不应该被修改。以前是通过将函数参数声明为const引用或者指向const的指针来解决这种问题。但是在这里show()方法没有任何参数,它所使用的方法是由方法调用隐式地提供。C++的解决方法是将const关键字放在函数的括号后面。

show()函数的声明:

void show() const;

函数定义开头:

void Stock::show() const {...}

以这种方式声明和定义的类函数被称为const成员函数。就像应尽可能将const引用和指针用作函数形参一样,只要类方法不修改调用对象,就应将其声明为const。

2、类作用域

在类中定义的名称(如类数据成员名和类成员函数名)的作用域都为整个类,作用域为整个类的名称只在该类中是已知的,在类外是不可知的。

2.1、作用域为类的常量

有时候,使符号常量的作用域为类很有用。例如,类声明可能使用字面值30来指定数组的长度,由于该常量对于所有对象来说是相同的,因此创建一个由所有对象共享的常量是个不错的主意。

class Bakery

{

private:

        const int Months=12;   //该常量并不是由所有对象共享

        double costs[Months];

}

有两种方式可以实现这个目标,且效果相同。

第一种方式是在类中声明一个枚举。在声明中声明的枚举的作用域为整个类。因此可以用枚举为整形常量提供作用域为整个类的符号名称。

class Bakery

{

private:

        enum {Months=12};

        double costs[Months];

}

这种方式声明枚举并不会创建类的数据成员。也就是说,所有对象中都不包含枚举。Months只使一个符号名称,在作用域为整个类的代码中遇到它时,编译器将用30来替换。

由于这里使用枚举只使为了创建符号常量,并不打算创建枚举类型的变量,因此不需要提供枚举名。在很多实现中,ios_base类在其共有部分中完成了类似的工作,诸如ios_base::fixed等标识符就来自这里。其中,fixed是ios_base类中定义的典型枚举量。

C++中提供了另一种在类中定义常量的方式——使用关键字static

class Bakery

{

private:

        static const int Months=12;

        double costs[Months];

}

这将创建一个名为Months的常量,该常量将与其他静态变量存储在一起,而不是存储在对象中。因此,只有一个Months常量,被所有的Bakery对象共享。

推荐阅读