type
status
date
slug
summary
tags
category
icon
password
Property
成员函数是面向对象的概念,在类中定义的函数,一个函数作为类的成员,公有成员、私有成员或者保护成员。 成员函数根据类的不同,可以进行继承,根据公有私有的不同,调用方式也不同。
非成员函数就是普通函数,就是不是在类中定义的函数,普通函数可以随便调用,并且无法继承和封装。
设计Sales_data类
Sales_data
的接口包含:- 一个
isbn
成员函数,用于返回对象的ISBN
编号
- 一个
combine
成员函数,用于将一个Sales_data
对象加到另一个对象上
- 一个
add
的函数,执行两个Sales_data
对象的加法
- 一个
read
函数,将数据从istream
读入到Sales_data
对象中
- 一个
print
函数, 将Sales_data
对象的值输出到ostream
成员函数
类成员函数是类的一个成员,它可以操作类的任意对象,可以访问对象中的所有成员。成员函数的声明必须在类的内部,定义则既可以在类的内部也可以在类的外部。定义在类内部的函数是隐式的内联(inline)函数。
作为接口组成部分的非成员函数,例如
add
、read
和print
等,它们的定义和声明都在类的外部。this指针
成员函数通过一个名为
this
的隐式额外参数来访问调用它的对象。this
参数是一个常量指针,被初始化为调用该函数的对象地址,不允许改变this
中保存的地址。默认情况下,
this
的类型是指向类类型非常量版本的常量指针(类类型* const
),只能在 "成员函数" 的内部使用。this
也遵循初始化规则,所以默认不能把this
绑定到一个常量对象上,即不能在常量对象上调用普通的成员函数。this
形参是隐式定义的,任何自定义名为this
的参数或变量的行为都是非法的。可以在成员函数体内部使用this
,因此尽管没有必要,但还是能把isbn
定义成如下的形式:注:友元函数没有
this
指针,因为友元不是类的成员。只有成员函数才有this
指针。const成员函数
C++
允许在成员函数的参数列表后面添加关键字 const
,表示this
是一个指向常量的指针(类类型 * const
)。使用关键字const
的成员函数被称作常量成员函数。常量成员函数不能改变调用它的对象的内容。常量对象和指向常量对象的引用或指针都只能调用常量成员函数
const
对象可以调用非const
成员函数吗? ————> 不可以
- 非
const
对象可以调用const
成员函数吗? ————> 可以
const
成员函数内可以调用其它的非const
成员函数吗? ————> 不可以
- 非
const
成员函数内可以调用其它的const
成员函数吗? ————> 可以
权限可以被缩小但不能被放大,普通对象可以调用普通成员函数,也可以调用
const
成员函数,只是在调用const
成员函数时,无法进行’写’操作。而const
对象一定不能进行写操作,所以不能调用普通成员函数。并且,普通成员函数内部可以调用const
成员函数,而const
成员函数内部不能够调用普通成员函数。类作用域和成员函数
类本身就是一个作用域,成员函数的定义嵌套在类的作用域之内。
编译器处理类时器分两步处理类,首先会是编译成员声明,然后才轮到编译成员函数体(如果有的话)。因此,成员函数可以随意使用类的其他成员而无须在意这些成员的出现顺序。
在类的外部定义成员函数
成员函数可以定义在类定义内部,或者单独使用范围解析运算符
::
来定义。在类的外部定义成员函数时,成员函数的定义必须与类内部的声明相匹配。如果成员函数被声明为常量成员函数,那么它的定义也必须在参数列表后面指定
const
属性。同时,类外部定义的成员名字必须包含它所属的类名。函数名
Sales::avg_price()
使用作用域运算符::
来说明定义了一个名为avg_price
的函数,并且该函数被声明在类Sales_data
的作用域内。一旦编译器看到这个函数名,就能理解剩余的代码是位于类的作用域的。当avg_price
使用revenue
和units_sold
时,实际上它隐式地使用了Sales_data
的成员返回this对象的函数
可以定义返回
this
对象的成员函数:return
语句解引用this
指针以获得执行该函数的对象,即上面的调用返回total
的引用。实际上是将
this
对象(本身)作为左值返回,因此可以使用该函数的结果通过点运算符访问其他成员。而若是Sales_data Sales_data::combine(const Sales_data& rhs)
,则不作为左值且只能改变临时副本而不是原有对象的值。const
成员函数如果以引用形式返回 *this
,则返回类型是常量引用。令成员作为内联函数
定义在类内部的成员函数是自动内联的(隐式内联):
如果需要显式声明内联成员函数,建议只在类外部定义的位置说明
inline
。虽然无需在声明和定义的地方同时说明inline
,但这么做其实是合法的。不过,最好只在类外部定义的地方说明inline
,这样可以使类更容易理解在头文件中定义
inline
函数的原因一样,inline
成员函数也该与类定义在同一个头文件中重载成员函数
和非成员函数一样, 成员函数也可以被重载 ,只要函数之间在参数的数量和或类型上有所区别就行。成员函数的函数匹配过程同样与非成员函数作常类似。
基于const的重载
通过区分成员函数是否为
const
的,可以对其进行重载。因为非常量版本的函数对于常量对象是不可用的,在常量对象上只能调用const
版本的函数;在非常量对象上,尽管两个版本都能调用,但显然会选择非常量版本,因为是一个更好的匹配。如果是一个常量对象,
display
会调用const Screen &display(std::ostream& os) const;
如果是一个非常量对象,
display
会调用Screen &display(std::ostream& os);
定义类相关的非成员函数
通常需要定义一些辅助函数,比如
add
、read
和 print
等。这些函数从概念上来说属于类接口的组成部分,但实际上不属于类本身。如果非成员函数是类接口的组成部分,则这些函数的声明应该与类放在同一个头文件中,这样用户使用接口的任何部分都只需要引入一个文件。一般来说,执行输出任务的函数应该尽量减少对格式的控制,这样可以确保由用户代归来决定是有换行。