CPP-类定义(Class definitions)

  • Post author:
  • Post category:其他


Member function 的declaration和普通函数一样。仅有的差别是放在类的定义里面。同样数据成员的declaration和普通变量也一样,只是放在类的定义里面。保留字public和private用来实现信息隐藏。public暗示被宣称的属性在类的定义的后续部分是可见的。即到处都可获得。private暗示只能在类的内部获得。 如果没有指明是public或private,类中所有成员默认为private.

C++中成员的宣称可以以任何顺序放置,public 和private也可以任意放置。但通常public放于private之前。

Declaration: what the function is called, what parameters it has, and what result type it returns. 为了使用一个类,成员函数的定义,包括函数的完整实现,必须存在。c++中,有两种方法来定义成员函数,他们可以直接放在内中间,也可以单独放在内的定义之外。例如,我们可以定义如下类:

其中,三个简单函数的实现在类中间,另外三个函数的实现在内之外:

class Clock {
public:
    void set(int hour, int min, int sec);
    int read_hour() {return h;}
    int read_min() { return m;}
    int read_sec() { return s;}
    void write(bool write_sec = true);
    void tick();
private:
    int h, m, s;
};

void Clock::set(int hour, int min, int sec)
{
    h = hour; m = min; s = sec;
}
void Clock::write(bool write_sec)
{
    cout << setw(2) << setfill('0') << h
        << ':' << setw(2) << setfill('0') << m;
    if (write_sec)
        cout << ':' << setw(2) << setfill('0') << s;
}
void Clock::tick()
{
    s = (s + 1) % 60;
    if (s == 0)
    {
        m = (m + 1) % 60;
        if (m == 0)
            h = (h + 1) % 24;
    }
}

注意尽管数据成员没有在成员函数中定义,也没有作为亚元传递给成员函数,但成员函数能够直接访问数据成员,但这只局限在成员函数。如果我们有另外一个函数,并不是类Clock的成员函数,那么就不能访问h,m和s. 当在一个成员函数内使用数据成员名字时,暗示数据成员属于当时成员函数被调用的类。成员函数不是普通函数,他们有独特的性质。例如:成员函数能直接访问类中的数据成员。当成员函数在所属类的外部被定义时,不能直接写成员函数的名字,必须指明此成员函数属于那个类。

在类的内部直接定义成员函数显得很方便,由于写的东西较少,但也应该小心,因为程序的可读性会降低。

关于成员函数的位置,另外一些事情也必须清楚,这和c++编译器如何将成员函数转变为机器骂有关。当调用一个函数时候(适用普通函数和成员函数),编译器通常产生机器码,这意味着程序要跳转到函数代码的位置,当函数机器码执行完毕,程序要跳转回调用的地方。函数机器码本身只存在于一个地址,因此所有调用都导致跳转到该地址。因此在每次调用时候必须有些指令保证程序的正确跳转和参数的正确传递。如果一个程序极其简单,只包含一条或两条语句,很可能这些额外指令比函数本身更复杂并要求更多的内存空间。此时,最好的情况是不执行跳转,而让程序在调用的地方直接开始执行,这种函数是inline function. inline function的代码在程序中所有调用的地方重复。

成员函数经常很简短,因此最好定义为inline function.如果成员函数的定义直接在类的内部,那么编译器默认将这些函数变为inline function. 由于比较长的函数不被认为是inline,因此,在类的内部定义多余几条语句的函数是不恰当的。这些函数应该单独定义。

将类的定义和函数定义分开还有其他好处,即使需要多书写代码,例如,程序看起来更好,更容易懂。依次所有函数应该在类的外部定义,即使函数很简短。如果我们想让函数成为inline, 我们总能用在函数定义时候使用inline。

例如:

inline void Clock::set(int hour,int min,int sec)
{
    h=hour;m=min;s=sec;
}