摘要:C++ 数据共享与保护的基本概念,包括标识符的作用域与可见性,对象生存期,类数据的共享,类共享数据的保护。
1.作用域
void Print(){
int a = 0;
std::cout << a << std::endl;
}
namespace XX{
void Print();
}
XX::Print(){
}
XX::Print()
???using 语句可以简化对命名空间内对象的访问: ???1.使用using XX::Print; 语句后,其后只需要通过Print 就可以调用该函数对象。 ???2.使用using namespace XX; 语句后,其后只需要通过函数名就可以调用XX 命名空间下的对象。
2.可见性
- 可见性:程序运行到某一点,能够引用到的标识符,称该标识符为可见的。
- 可见性隐藏规则:在多个具有包含关系的作用域声明的同名标识符,外层标识符在内层不可见。
- 全局变量:可以被本程序所有对象或函数引用。
- 在默认(全局)命名空间内声明的对象为全局变量,默认本编译单元内可以引用。
- 通过关键词
extern 声明引用的全局变量为其他编译单元中已经定义的全局变量。 - 通过关键词
static 声明的全局变量只能在本编译单元中使用,不能在其他编译单元用extern 声明引用。
3.对象的生存期
3.类数据的共享
面向结构编程: 程序模块:函数 数据共享方式:参数传递、全局变量
面向对象编程: 程序模块:类 数据共享方式:类的静态成员(类内数据共享)、类的友元(类外数据共享)
- 类的静态数据成员(类属性):类变量由该类所有实例对象共享,用
static 修饰。 设X 类的静态成员为m ,类的一个实例对象为x :
- 类的静态变量必须类内声明,类外定义。
- 在类的第一个实例对象初始化前初始化,在内存上只有一份副本。
- 类外定义时通过
X::m 进行引用,定义后可以通过实例对象进行引用,如x.m 。
- 类的静态函数成员(类方法):主要是处理类属性或者处理该类下多个实例对象的方法,用
static 修饰。 设X 类的静态函数为func ,类的一个实例对象为x :
- 可以直接访问该类的静态数据和函数成员,不能访问非静态成员。
- 可以在类的第一个实例对象初始化前通过
X::func 进行调用。 - 在实例对象初始化可以通过
x.func 调用,但是为了代码的可读性,不推荐这样使用。
#include<iostream>
using namespace std;
class A {
public:
static int s_count;
static void set_count(int i) {
s_count = i;
}
void UsingCount(){
s_count++;
}
};
int A::s_count = 0;
int main() {
A::s_count;
A::set_count(11);
A a1;
a1.UsingCount();
cout << a1.s_count << endl;
A a2;
a2.UsingCount();
cout << a2.s_count << endl;
}
输出结果:
12
13
- 友元关系:一个类主动声明其他类或函数是他的友元,进而给他们提供本类的访问特许,用
friend 修饰。 - 友元函数:被一个类声明为友元的函数,在他的函数体内可以通过对象名访问类的私有和保护成员。
- 友元类:被一个类A声明为友元的另一个类B,类B内所有成员函数都是类A的友元函数。
#include<iostream>
using namespace std;
class A {
private:
int m_nums = 10;
friend class B;
};
class B {
public:
void Print(A& a) {
cout << a.m_nums << endl;
}
};
int main() {
A a;
B b;
b.Print(a);
}
结果输出:
10
4.类共享数据的保护
-
常对象:常对象的数据成员值在对象整个生存期间不能被更改。 ?设A 类的常对象为a ,常函数成员为func ,常数据成员为m : ??1. 声明语法:const A a; ??2. 常对象必须进行初始化,而且不能被更新(不能赋值或者调用普通成员函数)。 ??3. 常对象只能调用常函数成员。 -
常函数成员:能被常对象调用访问常数据成员。 ??1. 常函数成员声明语法:返回值类型 func(参数表)const; ??2. 常函数成员定义部分时要带上const 。 ??3. 常函数调用期间,因为目标对象视为常对象,所以只能调用常函数。 ??4. const 可以用于函数重载,通过非const 对象调用重载函数优先调用非const 的重载函数。 -
常数据成员:值在初始化后不能被更新。 ??1. 常数据成员声明语法:const 数据类型 m; 。 ??2. 常数据成员不能被赋值,构造函数只能通过初始化列表进行初始化。 ??3. 静态常数据成员在类外进行定义。
#include<iostream>
using namespace std;
class A {
public:
void Print()const {
cout << a << ',' << b << ',' << s << endl;
}
A(int i) :b(i) {};
private:
const int a = 1;
const int b;
const static int s;
};
const int A::s = 3;
int main() {
A a(2);
a.Print();
}
结果输出:
1,2,3
- 常引用:常引用所引用的对象被视为常对象。
??1. 常引用声明语法:const 数据类型 &引用名 。 ??2.非const 的引用只能绑定到普通对象。 ??3. 对于无需修改值的参数(复制构造函数),尽量使用const 进行应用
END
2021.10.8 第一次编辑
|