【C++之数据的共享与保护】生存期、类的静态成员、类的友元、常对象

生存期

静态生存期特点:
1、静态生存期与程序的运行期相同;
2、在命名空间作用域中声明的对象具有静态生存期;
3、在函数内部声明静态生存期对象,要冠以关键字:static
4、不会随着每次函数的调用而产生一个副本;
5、默认初始值为0。
动态生存期:函数体内部没有使用static的对象。

类的静态成员

类的静态成员使用和特点:
1、用关键字static声明;
2、在每个类中只有一个副本,由该类的所有对象共同维护和使用;
3、具有静态生存期,可以通过类名直接访问:类名::静态成员标识符;
4、必须在类外定义和初始化,用(::)来指明所属的类,如:int Point::count = 0;

类的静态函数成员使用和特点:
1、使用static声明的函数成员;
2、属于整个类,由该类的所有对象共享;
3、可以自由选择函数体定义在类内还是类外(不同于静态成员);
4、静态成员函数只能引用属于该类的静态数据成员或静态成员函数;
5、必须通过对象名才能访问非静态成员;

类的友元

类的友元:
1、友元是C++提供的一种数据共享机制,可以提高程序的效率和可读性;
2、友元破坏了数据封装和数据隐藏;
3、使用关键字:friend将其他函数或类声明为友元,分为友元函数和友元类;
4、通过将一个模块声明为另一个模块的友元,则一个模块能够引用到另一个模块中本是被隐藏的信息。

友元函数:
1、友元函数时在类声明中由关键字friend修饰说明的非成员函数,在它的函数体中能够通过对象名来访问private和protected成员;
2、访问对象中的成员必须通过对象名。
举例如下,getX是类A的友元函数,可以通过对象名来访问到类A的private访问属性的变量x。

class A {
public:
	friend int getX();
private:
	int x;
};

int getX() {
	A a;
	return a.x;
}

友元类:
一个类B为另一个类A的友元类,则类B的所有成员函数都是类A的友元函数,都能访问A类的私有和保护成员。如下所示,声明了类B是类A的友元类,因此类B可以通过类A的对象访问到类A的private访问属性的变量x。
需要注意的是,友元关系是单向的,不可继承的,如下程序例子,虽然类B是类A的友元类,但是并不能认为类A是类B的友元类,实际上,类A并不能访问到类B的隐藏成员。

class A {
public:
	friend class B;
private:
	int x;
};

class B {
public:
	int getAx() {
		A a;
		return a.x;
	}
};
常对象

对于类A来说,定义一个常对象const A a(3, 4);,其中a为常对象,不能被更新,常对象只能调用它的常成员函数。
用const修饰的类成员中,有常成员函数,具有的性质如下:
1、常成员函数不更新对象的数据成员,也不能调用类中的非常成员函数;
2、常成员函数说明格式类型说明符 函数名(参数表) const,即在函数声明后面加上关键字const
3、上述的const是函数类型的一个组成部分,因此在实现部分也要带const关键字
4、const关键字可以被用来参与对重载函数的区别
如下举例,类A中定义了重载函数getX(),一个是非常成员函数,一个是常成员函数,在主函数中,非常对象a1,调用函数getX(),会选择调用到非常成员函数getX(),并且可以访问到非常成员函数setX(),而对于常对象a2来说,只能调用到常成员函数getX()。

class A {
public:
	A(int _x) :x(_x) {};
	int getX() const {
		printf("调用到常成员函数\n");
		return x;
	}
	int getX() {
		printf("调用到非常成员函数\n");
		return x;
	}
	void setX(int _x) {
		x = _x;
	}
private:
	int x;
};

int main() {
	A a1(1);
	printf("x:%d\n", a1.getX());
	a1.setX(3);
	printf("x:%d\n", a1.getX());

	const A a2(2);
	printf("x:%d", a2.getX());
}
/*输出:
调用到非常成员函数
x:1
调用到非常成员函数
x:3
调用到常成员函数
x:2
*/

对于常引用做形参,在函数中可以防止被更改,即在函数体内不能更新常引用r所引用的对象,例如声明为void display(const double &r){},其中常引用r是无法被修改的,可以起到对数据的保护。倘若直接将类对象作为形参,则传入实参时,要调用构造函数,这样要花费时间,而如果用引用,则会更高效,但又担心函数体内对类对象的修改会影响到实参,故可以选择用常引用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值