设为首页 加入收藏

TOP

C++中类定义的细节(一)
2015-11-21 00:56:15 来源: 作者: 【 】 浏览:4
Tags:定义 细节

成员变量

每个类可以没有成员,也可以定义多个成员,成员可以是数据、函数或类型别名。

一个类可以包含若干公有的、私有的和受保护的部分。在 public 部分定义的成员可被使用该类型的所有代码访问;在 private 部分定义的成员可被其他类成员访问。protected可以被子类访问。

?

构造函数

与类同名,且没有返回值的函数,用于构造一个对象。

一般使用一个初始化列表来初始化数据成员,如下:

Sales_item() : units_sold(0),revenue(0.0){}

?

成员函数

在类内部,声明成员函数是必需的,而定义成员函数则是可选的。

在类内部定义的函数默认为 inline。

在类外部定义的成员函数必须指明它们是在类的作用域中。Sales_item::avg_price 的定义使用作用域操作符来指明这是Sales_item 类中 avg_price 函数的定义。

将const加加到形参表之后,就可以变为常成员函数,在该函数内不能修改成员变量的值,如: double avg_price() const;

const必须出现在声明和定义中,若出现一处,就会出现一个编译时错误。

ps:const成员函数可以区分重载函数

?

? 显示指定inline成员函数

可以在类定义体内部指定一个成员为 inline,作为其声明的一部分。或者,也可以在类定义外部的函数定义上指定 inline。在声明和定义处指定 inline都是合法的。在类的外部定义 inline 的一个好处是可以使得类比较容易阅读。像其他 inline 一样,inline 成员函数的定义必须在调用该函数的每个源文件中是可见的。不在类定义体内定义的inline成员函数,其定义通常应放在有类定义的同一头文件中。

?

? 定义一个类

class Test{

}; //注意分号不能少

声明一个类

class Test; //叫前向声明

?

? 因为只有当类定义体完成后才能定义类,因此类不能具有自身类型的数据成员。然而,只要类名一出现就可以认为该类已声明。因此,类的数据成员可以是指向自身类型的指针或引用,如下:

?

class LinkScreen {

Screen window;

LinkScreen *next;

LinkScreen *prev;

};

?

? 类的定义分号结束。分号是必需的,因为在类定义之后可以接一个对象定义列表。定义必须以分号结束:

class Sales_item{ /* ... */ };

class Sales_item{ /* ... */ } accum, trans;

?

? 隐含的this指针

成员函数具有一个附加的隐含形参,即指向该类对象的一个指针。这个隐含形参命名为 this,与调用成员函数的对象绑定在一起。成员函数不能定义this 形参,而是由编译器隐含地定义。成员函数的函数体可以显式使用 this 指针,但不是必须这么做(比如return *this;)。如果对类成员的引用没有限定,编译器会将这种引用处理成通过 this 指针的引用。

?

? const 成员函数返回*this

在普通的非 const 成员函数中,this 的类型是一个指向类类型的 const指针。可以改变 this 所指向的值,但不能改变 this 所保存的地址。在 const 成员函数中,this 的类型是一个指向 const 类类型对象的const 指针。 既不能改变 this 所指向的对象, 也不能改变 this 所保存的地址。

****不能从 const 成员函数返回指向类对象的普通引用。const 成员函数只能返回 *this作为一个 const 引用。****

?

? 基于const的重载

基于成员函数是否为 const, 可以重载一个成员函数;同样地,基于一个指针或者引用形参是否指向 const,可以重载一个函数。const对象只能使用 const 成员。非 const 对象可以使用任一成员,但非 const 版本是一个更好的匹配。

?

? 可变数据成员

可变数据成员(mutable data member)永远都不能为 const(冲突),甚至当它是const 对象的成员时也如此。因此,const 成员函数可以改变mutable 成员。要将数据成员声明为可变的,必须将关键字 mutable 放在成员声明之前:

mutableint num;

?

? 形参表和函数体处于类作用域中

在定义于类外部的成员函数中,形参表和成员函数体都出现在成员名之后。这些都是在类作用域中定义,所以可以不用限定而引用其他成员。

charScreen::get(index r, indexc) const

{

index row = r * width; // compute the row location

return contents[row + c]; // offset by c to fetch specifiedcharacter

}

该函数用 Screen 内定义的 index 类型来指定其形参类型。因为形参表是在 Screen 类的作用域内,所以不必指明我们想要的是 Screen::index。我们想要的是定义在当前类作用域中的,这是隐含的。同样,使用 index、width 和contents 时指的都是 Screen 类中声明的名字。


? 函数返回类型不一定在类作用域中

与形参类型相比,返回类型出现在成员名字前面。如果函数在类定义体之外定义,则用于返回类型的名字在类作用域之外。如果返回类型使用由类定义的类型,则必须使用完全限定名。例如,考虑 get_cursor 函数:

classScreen {

public:

typedef std::string::size_type index;

index get_cursor() const;

};

inline Screen::index Screen::get_cursor() const

{

return cursor;

}

?

?

? 构造函数

Sales_items(); 对象在栈区

Sales_item*p=new Sales_item(); 对象在堆区

?

ps:构造函数不能声明为const。

Sales_item()const; //error

pps:与其他函数相同的是,构造函数具有名字(与类名相同),形参表,函数体,不同的是无返回值,返回类型,且包含一个构造函数初始化列表:

Sales_item::Sales_item(conststring &book):isbn(book), units_sold(0), revenue(0.0) { }

等价于

Sales_item::Sales_item(conststring &book)

{

isbn = book;

units_sold = 0;

revenue = 0.0;

}

注意:这个构造函数给类 Sales_item 的成员赋值,但没有进行显式初始化。不管是否有显式的初始化式,在执行构造函数之前,要初始化 isbn 成员。这个构造函数隐式使用默认的 string 构造函数来初始化 isbn。执行构造函数的函数体时,isbn成员已经有值了。该值被构造函数函数体中的赋值所覆盖。

从概念上讲,可以认为构造函数分两个阶段执行:(1)初始化阶段;(2)普通的计算阶段。计算阶段由构造函数函数体中的所有语句组成。

不管成员是否在构造函数初始化列表中显式初始化,类类型的数据成员总是在初始化阶段初始化。初始化发生在计算阶段开始之前。在构造函数初

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇HDU 5340-Three Palindromes(Mana.. 下一篇LeetCode - Merge Intervals

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: