目录
1. 友元
1.1 友元函数
友元函数不是当前对象的成员函数,但它可以访问该类的所有成员。
在类中声明友元函数时,需在其函数名前加上关键字friend
。此声明可放在公有私有保护部分。可以定义在类的内部,也可以定义在类的外部。
1.1.1将非成员函数声明为友元函数
class stu{
private:
int n,m;
public:
stu(int a,int b)
{
n=a;
m=b;
}
friend int function(stu &obj);
};
int function(stu &obj)
{
return obj.m+obj.n;
}
注意
(1) 友元函数不是成员函数,在类外定义时,不必加上 类名::
。
(2) 友元函数不是类的成员,它不能直接访问对象的数据成员,也不能通过this
指针访问对象的数据成员,它必须通过作为入口参数传递进来的对象名(或对象指针、对象引用)来访问对象的数据成员。
(3) 友元提供了不同类之间的成员函数之间、类的成员函数与一般函数之间进行数据共享的机制。尤其当一个函数需要访问多个类时,友元函数十分有用,普通成员函数只能访问其所属的类,但是多个类的友元函数能够访问相关的所有类的数据。
1.1.2 将成员函数声明为友元函数
一个类的成员函数也可以作为另一个类的友元函数,它是友元函数的一种,称为友元成员函数。友元成员函数不仅可以访问自己所在类中的所有数据,也可以访问friend
声明所在类的对象中的所有成员。
注意
(1) 一个类的成员函数作为另一个类的友元函数时,必须先定义这个类。并在声明友元函数时,要加上成员函数所在的类名
friend void stu::showStuScore(Score &sc);
(2) 注意向前引用 记得提前声明
1.2 友元类
友元类的说明方法是friend 类名;
此语句可以放在公有部分也可以放在私有部分
例如
class y{
...
};
class x{
...
friend y;//声明类y是类x的友元类
...
};
当一个类被说明为另一个类的友元类时,它的所有成员函数都成为另一个类的友元函数。
友元关系是单向的,不具有交换性。
友元关系也不具有传递性。
2. 类的组合
复杂的对象可以由比较简单的对象以某种方式组合而成,复杂对象和组成它的简单对象之间的关系是组合关系。
在类中内嵌另一个类的对象作为数据成员,称为类的组合。该内嵌对象称为对象成员,又称子对象。
例如
class Y{
...
};
class X{
Y y;//类Y的对象y为类X的对象成员
...
};
使用对象成员要着重注意的问题是对象成员的初始化,即类X的构造函数如何定义的问题。
当创建类的对象时,如果这个类有内嵌的对象成员,那么内嵌对象成员也将被自动创建。因此,在创建对象时既要对本类的数据成员初始化,又要对内嵌的对象成员进行初始化。
class X{
类名1 对象名1;
类名2 对象名2;
...
类名n 对象名n;
};
一般来说,类X的构造函数的定义形式如下
X::X(形参表0):对象名1(形参表1), ... , 对象名n(形参表n)
{
类X的构造函数体
}
冒号后面的部分是对象成员初始化列表,各对象成员的初始化列表用逗号分隔。
当调用构造函数X::X()
时首先,按各对象成员在类声明中的顺序依次调用它们的构造函数,对这些对象成员初始化。最后,再执行X::X()
的构造函数体初始化类中的其它成员。
析构函数的调用顺序与构造函数的调用顺序相反。
注意
(1) 声明一个含有对象成员的类,首先要创建各成员对象。
(2) 在调用构造函数初始化的同时,也要对对象成员进行初始化,因为它也属于此类的成员
3. 共享数据的保护
3.1 常引用
在说明引用时用const修饰,则被说明的引用为常引用。常引用所引用的对象不能被更新。
如果用常引用作为形参,便不会产生对实参的不希望的更改。
3.1.1 常引用的说明形式如下
const 类型& 引用名;
例如
int a=5;
const int& b=a; //b是a的一个引用,它所引用的对象,不允许被改变 如b=12;就是错误的。
3.1.2 例:常引用作函数参数
#include <iostream>
using namespace std;
int add(const int&,const int&);
int main()
{
int a=20,b=30;
cout<<a<<"+"<<b<<"="<<add(a,b)<<endl;
return 0;
}
int add(const int& i,const int & j) //函数add形参是常引用
{
return i+j;
}
3.2 常对象
在说明对象是用const修饰,则说明的对象为常对象。常对象中的数据成员为常量且必须要有初值。常对象中的数据成员值在对象的整个生存期内不能被改变。
3.2.1 常对象的说明形式
类名 const 对象名[(参数表)];
或
const 类名 对象名[(参数表)];
在定义对象时必须初始化,而且不能被更新。
注意
常对象不能调用普通的成员函数,只能调用常成员函数。
3.3 常对象成员
C++ 可以在声明类时将其中的成员声明为const
,即声明为常数据成员和常成员函数。
3.3.1 常数据成员
类的数据成员可以是常量或常引用,使用const
说明的数据成员称为常数据成员。
只能通过构造函数初始化列表对其初始化,其他任何函数都不能对该成员赋值。
例如
程序中定义如下常数据成员
const int year;
const int month;
const int day;
构造函数格式如下
Date::Date(int y,int m,int d):year(y),month(m),day(d)
{}//在函数体中直接赋值是非法的
常数据成员初始化之后值是不能被改变的。
3.3.2 常成员函数
在类中使用const
说明的函数为常成员函数。
3.3.2.1 常成员函数的说明形式
类型 函数名(参数表) const;
const
是函数类型的一个组成部分,因此在声明函数和定义函数时都要有关键字const
在调用时不必加。
3.4 说明
(1) 常成员函数可以访问二常数据成员,也可以访问普通数据成员。常数据成员可以被常成员函数访问,也可以被普通成员函数访问。
普通成员函数和常成员函数的访问特性比较
函数类型 | 普通数据成员 | 常数据成员 | 常对象的数据成员 |
---|---|---|---|
普通成员函数 | 可以访问,也可以改变值 | 可以访问,不可以改变值 | 不允许访问和改变值 |
常成员函数 | 可以访问,不可以改变值 | 可以访问,不可以改变值 | 可以访问,可以改变值 |
(2) 如果将一个对象说明为常对象,则通过该对象只能调用它的常成员函数,不能调用普通成员函数。
(3) 常成员函数不能更新对象的数据成员,也不能调用该类的普通成员函数。