关于C++的几篇博客,参考人民邮电出版社的《C++ Primer 中文版》一书。
本章着重介绍有关类的基本知识。
第十二章 类
C++用类来定义自己的抽象数据类型。
之所以有必要存在类的概念,是因为,数据抽象既能够隐藏对象的内部表示,同时仍然允许执行对象的公有(public)操作。这种方式更接近人对事物的认知。
第一节 类的基本组成
类的基本组成包括:数据成员、成员函数。它们的属性有三种:private,public,protected。
其中,构造函数和析构函数是类的一种特殊的成员函数,这里我们只简单提及构造函数的基本概念。关于构造函数和析构函数的具体内容,将会在后续章节介绍继承、虚函数等概念的时候再做具体介绍。
接下来,我们用一个例子来描述类的基本组成。
一、构造函数
1、构造函数,是一个特殊的、与类同名的成员函数,用于给每个数据成员设置适当的初始值。
2、一般使用一个构造函数初始化列表,来初始化对象的数据成员,如例1.
二、成员函数:
1、在类内部,成员函数必须做声明,但可以不做定义。
2、成员函数定义在类内部时,默认为inline;定义在类外部时,注意两点:第一,函数名前面需用作用域操作符指明该函数是属于哪个类的成员函数(如例1);第二,不默认为inline。(inline:内联函数。当调用inline函数时,编译器将试图在同一行内扩展该函数,这样的执行效率高。)
3、在例1中,avg_price()是const成员函数,这种成员函数不能改变其所在对象的数据成员。此外,const在声明和定义中都需要注明,否则会出编译错误。一般地,当成员函数并不做修改类的数据成员的操作时,就定义为const的。比如,一些定义在类内部的具有打印(print)、显示(display)等输出功能的const成员函数。
三、数据成员:
public:可被使用该类的所有代码访问,即可被类外的代码访问
private:只可被类内部的代码访问。一般数据成员都习惯定义为private的,这样就只能是类内的成员函数才可能修改数据成员,方便查找运行错误。
protected:哇哦,这个复杂了。参考这篇博客,讲得比较清楚:blog.csdn.net/luoruiyi2008/article/details/7179788
下面,我们具体讲解protected的属性。书上原文是这么介绍的:
protected是private和public的混合(或折中):
a. 在没有继承的情况下,和private一样,protected只能被类内部代码访问,外部的使用类的代码不可访问
b. 基类的protected,可以被派生类内部直接访问
c. 基类的protected,不可以被使用派生类的外部代码直接访问(直译:另外,protected还有另外一个重要特性:派生类对象如果要访问基类protected成员只有通过派生类对象,派生类不能访问基类对象的protected成员。)
关于protected,将会在后续涉及到继承的章节中继续讲解。目前到这里,还是有点似懂非懂的,嗯...比较麻烦,后面再慢慢一点点深入理解吧!
PS: 关于类的其他几点总结
1、当类定义体完全完成后,才能定义类,因此类不能具有自身类型的数据成员。然而,只要类名一出现,就可以认为该类已声明。因此,类的数据成员虽然不能是自身类型,但可以是指向自身类型的指针或引用。
其中,构造函数和析构函数是类的一种特殊的成员函数,这里我们只简单提及构造函数的基本概念。关于构造函数和析构函数的具体内容,将会在后续章节介绍继承、虚函数等概念的时候再做具体介绍。
接下来,我们用一个例子来描述类的基本组成。
// 例1:
class Sales_item {
public:
double avg_price() const;
Sales_item(): units_sold(0), revenue(0.0) {}
private:
std::string isbn;
unsigned units_sold;
double revenue;
};
double Sales_item::avg_price() const
{
if (units_sold)
return revenue/units_sold;
else
return 0.0;
}
一、构造函数
1、构造函数,是一个特殊的、与类同名的成员函数,用于给每个数据成员设置适当的初始值。
2、一般使用一个构造函数初始化列表,来初始化对象的数据成员,如例1.
二、成员函数:
1、在类内部,成员函数必须做声明,但可以不做定义。
2、成员函数定义在类内部时,默认为inline;定义在类外部时,注意两点:第一,函数名前面需用作用域操作符指明该函数是属于哪个类的成员函数(如例1);第二,不默认为inline。(inline:内联函数。当调用inline函数时,编译器将试图在同一行内扩展该函数,这样的执行效率高。)
3、在例1中,avg_price()是const成员函数,这种成员函数不能改变其所在对象的数据成员。此外,const在声明和定义中都需要注明,否则会出编译错误。一般地,当成员函数并不做修改类的数据成员的操作时,就定义为const的。比如,一些定义在类内部的具有打印(print)、显示(display)等输出功能的const成员函数。
三、数据成员:
public:可被使用该类的所有代码访问,即可被类外的代码访问
private:只可被类内部的代码访问。一般数据成员都习惯定义为private的,这样就只能是类内的成员函数才可能修改数据成员,方便查找运行错误。
protected:哇哦,这个复杂了。参考这篇博客,讲得比较清楚:blog.csdn.net/luoruiyi2008/article/details/7179788
下面,我们具体讲解protected的属性。书上原文是这么介绍的:
The protected access label can be thought of as a blend of private and public :
-
Like private members, protected members are inaccessible to users of the class.
-
Like public members, the protected members are accessible to classes derived from this class.
-
In addition, protected has another important property:
A derived object may access the protected members of its base class only through a derived object. The derived class has no special access to the protected members of base type objects.
protected是private和public的混合(或折中):
a. 在没有继承的情况下,和private一样,protected只能被类内部代码访问,外部的使用类的代码不可访问
b. 基类的protected,可以被派生类内部直接访问
c. 基类的protected,不可以被使用派生类的外部代码直接访问(直译:另外,protected还有另外一个重要特性:派生类对象如果要访问基类protected成员只有通过派生类对象,派生类不能访问基类对象的protected成员。)
关于protected,将会在后续涉及到继承的章节中继续讲解。目前到这里,还是有点似懂非懂的,嗯...比较麻烦,后面再慢慢一点点深入理解吧!
PS: 关于类的其他几点总结
1、当类定义体完全完成后,才能定义类,因此类不能具有自身类型的数据成员。然而,只要类名一出现,就可以认为该类已声明。因此,类的数据成员虽然不能是自身类型,但可以是指向自身类型的指针或引用。
例2:
class LinkScreen {
Screen window;
LinkScreen *next; // ok
LinkScreen &prev; // ok
LinkScreen other; // error
}
2、定义类型时,并不做内存空间的分配;当定义对象时,才为相应的对象分配存储空间。