C++类的定义与实现
梁唐 人气:0文章转自 微信公众号:Coder梁(ID:Coder_LT)
一、类的定义
根据C++ Primer
中的描述,类的定义是一种将抽象转换为用户定义类型的C++工具。也就是说类的实质是一种用户自定义类型,它可以将数目表示和操作数据的方法组合成一个整洁的包。
在实际开发当中,想要实现一个类,并编写一个使用它的程序是相对比较复杂的,涉及多个步骤。
通常,我们会将类的定义放在头文件当中,并将实现的代码放在源代码文件中。我们来看C++ Primer
当中的一个例子:一个关于股票买卖的类。
首先是类的定义,写在stock00.h文件中:
#ifndef STOCK00_H_ #define STOCK00_H_ #include <string> class Stock { private: std::string company; long shares; double share_val; double total_val; void set_tot() {total_val = shares * share_val;} public: void accquire(const std::string &co, long n, double pr); void buy(long num, double price); void sell(long num, double price); void update(double price); void show(); }; #endif
首先是关键字class
,它表示我们声明的是一个类,一般类名我们使用大驼峰命名法定义。
其次在这个类的定义当中,我们看到了两个新出现的关键字private
和public
。这两个关键字描述了对类成员的访问控制,使用类对象的程序,都可以直接访问公有部分(public
),但无法访问对象的私有成员。
想要获取私有成员,只能通过公有的成员函数。比如在上面这个例子当中,我们想要修改share_val
只能通过公有的方法sell
或buy
,而无法直接对变量的值进行修改。防止程序直接访问数据修改数据被称为数据隐藏。
除了public
和private
,C++当中还提供了第三个关键字叫做protected
,这个关键字和类的继承有关,我们将会在之后的文章当中进行讨论。
数据隐藏的思想其实是认为类中的成员变量的所有权应该属于类本身,当我们需要对类中的数据进行读取和修改的时候,应当通过类提供的公开方法,而不是直接操作类中值。这被认为是一种面向对象的思想,即只能通过类提供的方法访问数据,而不应该直接访问数据。
C++正是基于这种面向对象的思想设计的,所以类中的成员默认是private的,我们可以省去private关键字:
class World { float mass; char name[30]; public: void tellall(); ... };
我们从类的描述看上去很像是包含了成员函数以及数据隐藏的结构体,但实际上这是因为C++对结构体进行了拓展,让它具有了和类相同的特性。在C语言当中,结构体是没有这么多特性的。
比如我们可以给结构体设计构造函数,也可以给结构体添加成员函数,甚至结构体也可以继承、派生和多态。
它们之间唯一的区别是,结构体的默认类型是public
,而类是private
。所以通常使用类来实现对象,而结构体只用来结构化地存储数据。
另外多说一句,数据隐藏的面向对象理念并不适用于所有语言。比如Python,Python当中的类中的成员变量默认是public,且没有private
关键字。
二、类的实现
当我们完成了类定义之后, 还需要来实现类当中的函数。
比如我们在stock00.h当中定义了一个类:
#ifndef STOCK00_H_ #define STOCK00_H_ #include <string> class Stock { private: std::string company; long shares; double share_val; double total_val; void set_tot() {total_val = shares * share_val;} public: void accquire(const std::string &co, long n, double pr); void buy(long num, double price); void sell(long num, double price); void update(double price); void show(); }; #endif
1.成员函数
在这个定义当中,我们只是声明了函数,并没有具体实现函数的逻辑。
我们通常会在同名的cpp
文件当中实现,实现的时候,需要使用作用域解析运算符来表示函数所属的类:
void Stock::update(double price) { ... }
这样就表明了update
函数所属Stock
这个类,这也就意味着我们可以创建属于其他类的同名函数:
void Buffoon::update() { ... }
其次,我们在成员函数当中,可以访问private
限定的成员变量。比如说在show
函数当中,我们可以这样实现:
void Stock::show() { std::cout << company << shares << share_val << total_val << endl; }
虽然company
,shares
都是类的私有成员,但在成员方法当中,一样可以正常访问。
再次,我们在成员方法当中调用另外一个成员方法,可以不需要解析运算符。比如我们要在show函数内调用update
函数,直接使用update()
即可,而无需前面的Stock::。
2.内联函数
我们再回过头来看一下Stock
这个类的定义,在类的定义当中,有一个叫做set_tot
的函数。我们直接在类当中实现了逻辑。虽然同样是成员函数,但是在类当中直接实现的函数是有所区别的。在类声明当中实现的函数,会被视为是内联函数。
一般我们会把一些比较简短的函数在类的声明当中直接实现,当然我们也可以使用关键字inline
,手动指定某个函数是内联的。
class Stock { private: void set_tot(); public: ... }; inline void Stock::set_tot() { total_val = shares * share_val; }
加载全部内容