第四章 基于对象的编程风格(如何实现一个class)

4.1如何实现一个class

 

程序:class的用法:

class的声明

 

先从class开始,后接一个class名称(可任意)

class stack;
stack *pt=0;
void process(const stack&)

 

 

 

定义class:


class stack
{
 public:

 private:


};


class由两个部分组成,class的声明以及紧接着的主体。主体部分用一对大括号括住,并以分号结尾。主体内的两个关键字public和private,用来标示每个块“memeber访问权限”public可以在程序的任何地方被访问,private只能在class中的member function或者是classfriend.

 

以下是class stack的起始操作定义:

 

class stack
{
  public:
//操作函数如果执行成功就返回true
//pop和peek会将字符内容置于elem中
bool push(const string&);
bool pop(string &elem);
bool peek(string &elem);
bool empty();
bool full();
//size()定义于class本身中
//其他member则仅仅是声明
int size()
{
 return_stack.size();
}
private:
vector<string>_stack;
};

以上是stack的六个操作:用push把数值放入站内,pop取出stack内最后被pushed的元素。peek是查看,观察stack最后一个被pushed的数值。询问是否空是否满,元素个数。


这一份stack提供了六个操作行为,其元素被存储为_stack的string vector内。编码习惯是在data member之前加下划线。一下说明如何定义并使用stack class object:

void fill_stack(stack &stack,istream &is=cin)
{
 string str;
while(is>>str&&!stack.full())
stack.push(str);
cout<<"read in"<<stack.size()<<"elements\n";}

 

所有的member function都必须在class主体内进行声明。至于是否要同时进行定义,可自由决定。例如size()即是stack的一个inline member。要在class主体之外定义,前一节已介绍inline函数最好定义在头文件中。

 

member function.必须使用特殊的语法,目的在于分辨该函数究竟是属于哪一个class,如果希望该函数为inline,应该在最前面制定关键字inline

 

inline bool
stack::empty()
{
  return _stack.empty();
}
bool
stack::pop(string &elem)
{
  if(empty())
  return false;
  elem=_stack.back();
  _stack.pop_back();
  return true;
}


上述的stack::empty()告诉编译器(或者读者)说:empty()是stack class(而非vector或者string)的一个member。class名称之后的两个冒号(stack::)即所谓的class scope resolution(类作用域解析)运算符。

对inline函数而言,定义于clas主体内或者主体外并没有什么分别。然而就像non-member inline function一样,它也应该在头文件中,class定义及其inline member function通常都会被放在与class同名的头文件中。列如stack class定义和其empty()函数定义都应该放在stack.h头文件中。此即用户想要使用stack时应该包含的文件。


non-inline member function应该在程序代码文件中定义,该文件通常与class同名,其后接着扩展名.c,.cc,.cpp或.cxx(x代表恒放的+)以microsoft visual C++为例,它使用扩展名.cpp。disney feature animation这家公司的惯例是使用扩展名.c。另一家公司dreamwork animation习惯使用扩展名.cc。


程序:

以下便是stack member fuction 的定义。full()会将目前的元素个数拿来和底层vector的max_size()数值(此即vector的大小)做比较。push()则是在_stack未满的前提下将元素插入。

inline bool stack::full()
{
  return_stack.size()==_stack.max_size();
}
bool stack::peek(string &elem)
{
if(empty())
return false;
elem=_stack.back();
return true;
}
bool stack::push(const string &elem)
{
if(full())
return false;
_stack.push_back(elem);
return true;
}

虽然我们提供给用户一整组操作行为,但还是未能完成stacka的完整定义。下一节,我们会看到如何提供极为特殊的所谓初始化函数和终止函数,它们分别被称为construct(构造函数)和destructor(析构函数)

阅读更多

没有更多推荐了,返回首页