C++速成笔记(七)自用

一、常对象、常数据成员和常成员函数

既要使得数据能够在函数间共享,又要保证它不能被任意的修改,使用const限定,将其改为只读的。

常对象:

类名 const 对象名1(实参列表), 对象名2,......;
const 类名 对象名1(实参列表), 对象名2,......;

二者意义相同,表示该对象是一个const对象,只可读,不可写。

常对象中除了默认构造函数和析构函数外,只有用const限定过的成员函数才能够被调用。

非const函数不能被调用。

使用mutable修饰常对象中的数据成员,能够使得系统获得更改这一成员的权限,在实际应用中具有一定的价值。

常数据成员:在声明数据成员的时候使用const限定,如 const int a;

常数据成员不能被成员函数和非成员函数修改,只有构造函数的初始化列表能对其进行初始化。

class 类名 { //类体
…返回类型 函数名(形式参数列表) const //常成员函数定义
{
    函数体
}…
};

class 类名 { //类体
…返回类型 函数名(类型1 参数名1,类型2 参数名2,…) const; …
};

返回类型 类名::函数名(形式参数列表) const //常成员函数外部定义
{
    函数体
}

无论是声明还是定义常成员函数,都需要用const限定,若const写到返回类型前面,表示返回的数值是不可改的。

数据成员非常成员函数常成员函数
非常数据成员允许访问、可以修改允许访问、不能修改
常数据成员允许访问、不能修改允许访问、不能修改
常对象数据成员不能访问、不能修改允许访问、不能修改

1.在一个类中,如果有些数据成员的值允许修改,另一些数据 成员的值不允许修改,那么可以将一部分数据成员声明为const (常数据成员),使得其值不能被修改。而普通的成员函数可以修 改普通的数据成员,但只能访问常数据成员的值。

2.如果要求所有数据成员的值都不允许改变,可以将对象声明 为const的(常对象),那么只能用const成员函数访问数据成员, 且不能修改其值。这样,数据成员无论如何也不会被修改。

3.如果定义了一个常对象,只能调用其中的const成员函数,而 不能调用非const成员函数。如果需要访问对象中的数据成员,可将常对象中所有成员函数都声明为const成员函数,但应确保在函 数中不会修改对象中的数据成员

4.常对象中的成员函数不一定是常成员函数。如果在常对象中 的成员函数未加const声明,C++把它作为非常成员函数处理

5.常成员函数不能调用另一个非常成员函数。

二、常指针

类名 * const 指针变量名=对象地址; //常指针

始终保持其初值,不能修改指向,定义时就要初始化。指向对象的常指针。

常指针指向的对象可以是非常对象。常作为函数的形参使用。

const 类名 *指针变量名;

指向常对象的指针变量,不能通过该指针去修改指向的对象的值。但指针本身非常指针,可以任意改变指向。因此可以在定义的时候不初始化。

只要我们定义的指针是常对象指针,即使其指向的对象是非常对象,也不能通过该指针改变对象的内容。

该指针作为形参为了保护所指向的对象,不被修改。

三、常引用

const 类名 & 引用变量名;

既可以不生成对象的副本,作为形参,大大减少了空间,又可以保护原对象不被改变。还能够生成一个自己用的名字。

四、静态成员

static int count;

►①静态成员的名字是在类的作用域中,因此可以避免与其他类的成 员或全局对象名字冲突;

►②静态成员可以实施封装,可以是私有成员,而全局对象不可以。

►③静态成员是与特定类关联的,结构清晰。

静态数据成员是属于整个类的,他可以被该类下的任何对象调用。在该类中改变,在所有对象中都可以改变,但是不占用额外的空间,只占用一份空间。

相较于全局变量,他的作用域只在类中,更安全, 也简介。

同时可以在构造函数中对这个静态成员改变,例如每生成一个对象,都对count++。

►关于静态数据成员的说明:

►(1)通常,非静态数据成员存在于类类型的每个对象中,静态数据成员则独立于该类的任何对象,在所有对象之外单独开辟空间存储。在为对象所分配的空间中不包括静态数据成员所占的空间。

►(2)如果只声明了类而未定义对象,则类的非静态数据成员是不占存储空间的,只有在定义对象时,才为对象的数据成员分配空间。 但是只要在类中定义了静态数据成员,即使不定义任何对象,也为 静态数据成员分配空间,它可以在尚未建立对象时就被引用

►(3)访问静态成员时同样需要遵守公有及私有访问规则。

►(4)静态数据成员必须在类外部定义一次(仅有一次)静态成员不能通过类构造函数进行初始化,而是在类外定义时进行初始化。 定义静态数据成员的方式为:

数据成员类型 类名::静态数据成员名=初始化式;

他可以被用作默认实参。

可以直接通过 类名字::静态数据成员名 调用

五、静态成员函数

static int getcount() { return count; } //静态成员函数

静态成员函数也是类的一部分,直接使用类名字::函数名调用也可以直接用对象名字.函数名字调用。

静态成员函数没有this指针,因此无法访问本类中的非静态成员。

静态成员函数不能访问非静态成员。只是专门为了访问静态的数据成员的。因此他也不能被限制为const。

(谁调用非静态的成员函数,this指针就会指向谁,静态成员没有,只能访问静态的数据成员。)

在类外使用静态成员函数访问静态成员。

对象可以调用静态函数和非静态函数,

但是类的域运算符只能调用静态。

六、友元

将一个函数设置为友元函数,将一个类设置成友元类。

友元类的所有成员函数均可以访问有缘关系的类的非公有成员。

所以访问类的非公有成员具有两个用户:一个是自己类本身,一个是友元。友元关系是单向的。

#include <iostream>
#include <cmath>
using namespace std;
class Point { //Point类
public:
Point(int _x=0,int _y=0) : x(_x), y(_y) { }
private:
int x, y;//私有数据成员
friend double distance(Point& r1, Point& r2); //友元函数
};

distance函数就可以使用这个类中的私有成员x,y

class B; //类的前向声明 
class A { //A类 
public: 
A(int _a=0) : a(_a) { } 
void setb(B& r); 
private: 
int a; //私有数据成员 
}; 
class B { //B类 
public: 
B(int _b=0) : b(_b) { } 
private: 
int b; //私有数据成员 
friend void A::setb(B& r); 
};

由于类A中函数用到了B,对B做一个前向声明,之后在B的定义中,将类A中的函数设置为B的友元函数,称之为友元成员函数。

将一个类设置成友元类,则该类中所有的成员均可以访问类中的所有成员;

class 类名 { //类体
…
friend 友类名;
};
class 友类名 { //类体
…
};

利用友元,突破封装的限制,要在数据共享和信息屏蔽之间选择恰当的平衡点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值