如果这篇博客帮助到你,可以请我喝一杯咖啡~
CC BY 4.0 (除特别声明或转载文章外)
一 类的设计
步骤:
提供类声明
class className { private: data member declarations; public: member function prototypes; };
实现类成员函数
假设有一个加
Bozo
的类,有一个成员函数Retort()
char* Bozo::Retort() { ... }
二 构造和析构
当程序创建未被显式初始化的类对象时,总是调用默认构造函数
const 成员函数
const Stock land("Shepard");
land.show();
对于现在的 C++ 来说,编译器拒绝第二行。
因为 show()
的代码无法确保调用的对象不被修改。
将声明和定义修改为:
void show() const; // promise not to change invoking object
void stock::show() cosnt;
就像尽可能使用 const
引用和指针用作函数形参一样,只要类方法不修改调用对象,就应该将其声明为 const
构造与析构小结
通常,构造函数用于初始化类对象的成员,初始化应与构造函数的参数列表匹配。例如,类 Bozo
的构造函数的原型如下:
Bozo(const char* fname, const char* lname);
则可以用它来初始化新对象:
Bozo a = Bozo("Wang", "Shepard"); // primary form
Bozo b("Wang", "Shepard"); // short form
Bozo *pb = new Bozo("Wang", "Shepard"); // dynamic object
如果 构造函数只有一个参数 ,则将对象初始化为一个与参数类型相同的值时,该构造函数会被调用。例如:有这样一个构造函数:
Bozo(int age);
则可以使用下面任意一种方式初始化对象:
Bozo a = Bozo(21);
Bozo b(21);
Bozo c = 21; // special for one-argument constructors
默认构造函数 :
- 无参
- 全缺省
Bozo();
Bistro(const char* s = "Shepard");
三 this 指针
this 指针的类型
一般类型:类类型的 const 指针
被 const 修饰:const 类类型 const 指针
为前面的 stock 类添加比较两个价值的函数:
const Stock& Stock::topval(const Stock& s) const
{
if(s.total_val > total_val)
return s;
else
return *this;
}
四 对象数组
创建对象数组:
Stock mystuff[4]; // 4 个成员都调用默认构造函数
Stock stock[10] = {
Stock("NanoSmart", 12.5, 20),
Stock(),
Stock("Shepard", 130, 12.5),
// 后 7 个调用默认构造
};
初始化对象数组的方式 :首先使用默认构造函数创建数组元素,然后花括号中的构造函数先创建临时对象,然后将临时对象的内容复制到相应的元素中。
但是编译器可能会优化,直接使用花括号中构造函数的参数构造数组元素。
要创建对象数组,则这个类必须有默认构造函数
五 接口和实现
修改类的私有部分和实现文件属于 实现的变更 ;修改类的公有部分属于 接口变更 。实现变更改变了类的内部工作原理,接口变更改变了使用类的人可用的编码方式。
六 类作用域
类成员访问
在类中定义的名称(如类数据成员名和类函数成员名)的 作用域为整个类 ,作用域为整个类的名称只在该类中是已知的,在类外是不可知的。
在类外,构造函数名称在被直接调用时,才能被识别 ,因为它的名称与类名是相同。在其他情况下,使用类成员名时,必须根据上下文使用 直接成员操作符(.
),间接成员操作符 (->
) 或 作用域解析操作符(::
)。
作用域为整个类的常量
有时候,使符号常量的作用域为整个类很有用。另外,常量对于所有对象来说都是相同的,因此创建一个所有类共享的常量是个不错的主意(节省空间)。
注意下面的代码:
class Stock
{
private:
const int Len = 30;
char company[Len]; // Error
};
这是行不通的,因为声明类只是描述了对象的形式,并没有真正创建对象。因此,在对象被创建之前将没有用于存储值的空间。
<批注:数组大小需要在编译时确定,而 const 在运行时才会确定。 退一步来说,这种定义方式也不能实现多个类共享一个常量。>
有两种方式实现:
在类中声明一个枚举 类中的枚举作用域为整个类。
enum{ Len = 30 };
int array[Len];
这种方式声明的枚举并不会创建类数据成员。所有对象中不会包含枚举。编译器会用 30 替换 Len
<批注:const int Len
不能算真正从常量,它算“常变量”。C++ 标准中指出:整数常量表达式是整数或无范围的枚举类型>
使用 static
static const int Len = 30;
int array[Len];
该常量与其他静态变量存储在一起,而不是存储在类中。
参考资料 :
《C++ Primer Plus 5 edition》