第六章 类与对象之类的其他成员

类的其他成员

类定义中除了一般指定访问权限的成员,还可以定义各种特殊用途的成员。
常成员:常数据成员、常成员函数、常对象
静态成员:静态数据成员、静态成员函数
友元:友元函数、友元类

常成员

常数据成员

常数据成员:在类中定义的不能修改其值的一些数据成员,类似于常变量,虽然是变量,也有自己的地址,但是一经赋初值,便不能再被修改。
适用于类中定义一些初始化之后不希望被修改的数据成员。
常数据成员表示它在某个对象生存期内是常量, 即在对象生成时给出常量值,在对象生存期内其值不可改变。而对于整个类而言,不同的对象其常数据成员的值可以不同。

定义方法:const 类型名 变量名;

类中的常数据成员只能通过构造函数的参数初始化表进行初始化,任何其他函数都不能对该成员赋值。

const int M; //说明常数据成员
Mclass() : M(5) { } //用初始化列表对常数据成员赋值

加粗样式
注意:
不能在类声明中初始化常数据成员。以下用法是错误的:

class A 
{
const int SIZE = 100; // 错误,企图在类声明中初始化常数据成员
int array[SIZE]; // 错误,未知的 SIZE 
};
void testFun()
{ //M++; //错误,不能在成员函数中修改常数据成员,已经初始化了,不能再次改变了
k++; //可以修改一般数据成员
}

加粗样式

常成员函数

常成员函数的引入:由于数据封装在类的内部,需要小心处理,不能破坏成员数据。
可以使用const来保护数据成员——常数据成员,
也可以使用const来保护成员数据不被成员函数改变,这种成员函数称为常成员函数。它告诉编译器,这个函数是安全的,不会改变对象的数据成员的值(一个没有被明确声明为常成员函数的成员函数被认为是危险的,因为它可能会改变数据成员的值)

常成员函数的说明格式: 类型说明符 函数名(参数表) const;

 const是函数类型的一个组成部分,因此在函数的实现部分也要带关键字const。
常成员函数不能更新对象的数据,也不能调用非const修饰的成员函数(静态成员函数、构造函数除外)

void constfun()const
{x++;y++}//错误 不可以改!!!!!1

const参与函数的重载

#include <iostream>
using namespace std;
class Cone
{
public:
Cone(int m,int n){x=m;y=n;}
void print(){
cout<<"没有使用常量成员函数"<<endl; cout<<x+y<<endl; }
void print() const{
cout<<"使用了常成员函数"<<endl;
cout<<x+y<<endl;
}
private:
int x, y;
};
int main()
{
Cone one(3,4);
o.print();
const Cone tow(3,6);//常对象two只能调用它的常成员函数void print( ) const 、静态成员函数、构造函数(具有公有访问权限)
t.print();
}

/*
输出
没有使用常量成员函数
7
使用了常成员函数
9
*/

常对象

如果一个对象在初始化后不需要修改其值,可定义为常对象。
常对象的说明形式:

类名 const 对象名[(参数表)];
或者 const 类名 对象名[(参数表)]; 

定义常对象时必须进行初始化,而且不能被更新。
说明:
(1)C++不允许直接或间接更改常对象的数据成员(数据成员的值,包括公有、私有访问权限的所有数据成员) 。
(2)C++规定常对象只能调用它的:
常成员函数
静态成员函数
构造函数(具有公有访问权限)。
对比:普通对象既可以调用非常成员函数,也可以调用常成员函数(具有公有访问权限的任何的成员函数)public

静态成员

 声明为static的类数据成员称做静态数据成员
 声明为static的类成员函数称做静态成员函数
能在类的范围内共享数据。
• 静态成员不属于某一个单独的对象,而是为类的所有对象所共有
• 根据静态存储的特点,当对象不存在时,仍可以访问该静态成员。
• 静态成员函数的作用不是为了对象之间的沟通,而是为了能处理静态数据成员: 保证在不依赖于某个对象的情况下,访问静态数据成员。

静态数据成员

 声明方法:static 类型名 变量名;  类的静态数据成员有单独的存储区,不管创建了多少该类的对象,所有对象的静态数据成员共享该存储区,即该类的所有对象维护该成员的同一个拷贝。静态数据成员属于类,在类的范围内有效,可以是公有或私有。
 类的定义只是给出对象构成的说明,真正的存储空间分配是在对象定义时,由于静态数据成员属于类不属于对象,系统为对象分配存储空间时,不包括静态数据成员的存储空间。所以,静态数据成员的存储空间需单独分配,且只分配一次。为静态数据成员分配存储空间称为静态数据成员的定义。
 不能在成员初始化列表中进行初始化,必须在类外定义和初始化,用(::)来指明所属的类:

 类型 类名::静态数据成员[=初始化值]; //必须进行声明

 如果未进行初始化,则编译器自动赋初值(默认值是0)
含有静态数据成员的类和静态数据成员的定义如:

class A
{ int n;
static int s;
} CMyclass;
int A::s=0//在类外定义和初始化

注意:
sizeof 运算符不计算静态成员变量,sizeof(CMyclass)等于4。使用静态数据成员可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态数据成员只存储一处,供所有对象共用。

静态成员函数

 静态成员函数用于操作静态数据成员,它只能直接引用属于该类的静态数据成员或静态成员函数
 类的静态成员是属于类的而不是属于哪一个对象的,它们都不是对象成员。通常定义成公有的,因此,对静态成员的引用不需要用对象名。类外代码可以使用类名和作用域操作符来调用静态成员函数。
 静态成员函数没有this指针,只能对静态数据操作。
定义静态成员函数的格式如下:

static 返回类型 静态成员函数名(参数表);

与静态数据成员类似,调用公有静态成员函数的一般格
式有如下几种:

类名::静态成员函数名(实参表)
对象. 静态成员函数名(实参表)
对象指针->静态成员函数名(实参表)

静态成员函数在类外定义时不用static前缀。

class A
{
public:
static void func();
};

void A::func()
{
//....实现
} 

说明:

(1)静态成员函数在类外定义时不用static前缀。
(2)静态成员函数主要用来访问同一类中的静态数据成员。
(3)私有静态成员函数不能在类外部或用对象访问。
(4)可以在建立对象之前处理静态数据成员。
(5)编译系统将静态成员函数限定为内部连接:与现行文件相连接的其他文件中的同名函数不会与该函数发生冲突,维护了该函数使用的安全性,这是使用静态成员函数的另一个原因。
(6)静态成员函数中没有this指针。
(7)静态成员函数不能直接访问类中的非静态数据成员。如有需要,可以通过***指向对象的指针或对象的引用***访问该对象的非静态成员。

友元

问题的提出:类外访问类的私有成员
类具有封装和信息隐藏的特性。只有类的成员函数才能访问类的私有成员,其他函数无法访问私有成员。非成员函数能够访问类中的公有成员,但是假如将数据成员都定义为公有的,这又破坏了隐藏的特性。
在某些情况下,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,而影响运行效率。 运算符重载的某些场合需要使用友元
解决:使用友元
友元是一种定义在类外部的普通函数,但它需要在类体内进行说明,为了和该类的成员函 数加以区别,在说明时前面加以关键字friend。友元不是成员函数,但是他能够访问类中的私有成员。友元的作用在于提高运行效率,但 是,他破坏了类的封装性和隐藏性,使得非成员函数能够访问类的私有成员。
友元可以是函数,称为友元函数;
友元也可以是类,称为友元类。
友元关系不是对称关系。即 Y 是 X 的友元,不意味着 X 是 Y 的友元。
友元关系不是传递关系。即 Y 是 X 的友元,Z 是 Y 的友元,但 Z 不一定是X的友元。

友元函数

 如果在本类(类A)以外的其他地方定义了一个函数(函数B) 这个函数可以是不属于任何类的非成员函数,
 也可以是其他类的成员函数,
 普通函数B声明为类A的友元,在类A体中用friend对其(函数B)进行声明,此函数就称为本l类(类A)的友元函数。
格式:

friend 类型 B(函数参数)

 友元函数(函数B)可以访问这个类(类A)的私有成员。
一定要先定义类,再定义友元函数,否则编译报错友元函数不是类的成员函数,不受访问权限的限制;不影响对私有成员的访问。

友元函数的几个问题

  1. 普通函数声明为友元主要是为了访问该类的私有成员
  2. 普通函数作为友元函数时,由于函数没有this指针,因此,函数参数存在以下情况:
    ① 如果要访问该类的非static成员,需要将该类的对象作为形参
    ② 要访问static成员,或全局变量,不需要对象作为形参
  3. 友元函数不受访问权限的限制
  4. 友元函数的代码可以在类内实现,也可以在类外实现

友元类

class F
{ 
……………
private:
A obj1;
};

A是另一个类,F类的成员函数要访问A的私有成员,此时,需要在A类中,把类F声明为A的友元
若F类是A类的友元类,则***F类的所有成员函数都是A类的友元函数***
 友元类通常设计为一种对数据操作或类之间传递消息的辅
助类
 友元类的声明格式:

friend class 类名;
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jdicat

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值