数据的共享与保护

C++
2024-12-25 08:46

一、标识符的作用域与可见性


二、对象的生存期

静态生存期

  • 这种生存期与程序的运行期相同。

  • 在文件作用域中声明的对象具有这种生存期。

  • 在函数内部声明静态生存期对象,要冠以关键字 static

动态生存期

  • 块作用域中声明的,没有用static修饰的对象是动态生存期的对象(习惯称局部生存期对象)。

  • 开始于程序执行到声明点时,结束于命名该标识符的作用域结束处。

三、变量的生存期与可见性综合示例



思考:在函数内部定义的普通局部变量和静态局部变量在功能上有何不同?计算机底层对这两类变量做了**

怎样的不同处理?

  • 局部作用域中的静态变量: 不会随着每次函数的调用而产生一个副本,也不会随着函数的返回而失效,定义时未指定初值的会被以0初始化

  • 局部作用域中的全局变量:诞生于声明点,结束于声明所在块执行完毕之时,并且不指定初值意味着初值不确定

四、类的静态成员 static

静态成员函数/变量本质上是全局函数/变量,哪怕一个对象都不存在,类的静态成员都还是存在的。

那为什么还要设置静态成员而不直接设置成全局函数/变量呢?

  • 是为了将和某些类紧密相关的全局变量和函数写到类里面,使其看上去像一个整体,便于维护和理解。

注:私有的静态成员在类外依然不能访问

静态成员变量


class A{
    int n;
    static int s;
}
int A :: s = 2;  //类外初始化
  • 所有对象共享,维护同一个副本,即对象 n1 修改其值,对象 n2 中的值也会改变。

  • sizeof(A) = 4;sizeof不会计算静态成员变量

  • 静态成员变量必须在类外进行一次说明或初始化,否则编译能通过但链接不能通过

静态成员函数


普通成员函数必须具体作用于某个对象(即通过 对象名. 访问),

而静态成员函数并不具体作用于某个对象,不需要通过对象就能访问。

静态成员函数的访问方式:

  • 类名::成员名(无须对象,直接通过类名访问)

Point::showCount();
  • 对象名.成员名

A a; 
a.s( );

但并不意味着只作用于a上面

  • 指针->成员名

A *p; 
p->s( );

但并不意味着只作用于a上面

  • 引用.成员名

A &q = a; 
q.s( );

但并不意味着只作用于a上面

注:静态成员函数要访问非静态成员变量必须通过对象名.

class A
{
    int x;
public:
    static void func(A a)
    {
        cout << x; //ERROR!!!
        cout << a.x;
    }
}

五、类的友元 friend


友元函数


友元类


特别注意:友元关系不能继承;不能传递;单向 !

六、共享数据的保护 (const)


Java 中没有 const 关键字,与之替代的是 final

常对象

用 const 修饰的对象

  • 常量对象的值不可被修改

  • 常量对象不能执行非常量成员函数,因为非常量成员函数有可能对成员变量进行修改;

  • 常量对象可以执行常量成员函数

例:

class A{
	public:
		A(int i, int j){
			x = i;
			y = j;
		}
	private:
		int x, y;
};

A const a(3,4); //常对象a,不能被更新

常成员

用 const 修饰的对象成员

常成员函数


例:


常成员函数执行期间不应该修改其所作用的对象**,即

  • 在常量成员函数中不能修改成员变量的值(静态成员变量除外)

  • 也不能调用同类的非常量成员函数(静态成员函数除外)

例:

class A{
    public:
        int value;
        void setValue() const;
        void func();
}
void A :: setValue(){
    value = 0; //wrong 常量成员函数中不能修改成员变量的值
    func(); //wrong 常量成员函数中不能调用同类的非常量成员函数
} 
const A a;
a.value = 100; //wrong 常量对象的值不可被修改
a.func(); //wrong 常量对象不能执行非常量成员函数
a.setValue(); //right 常量对象可以执行常量成员函数

常数据成员

使用 const 说明的数据成员

  • 常数据成员 const 只能通过构造函数的初始化列表来获得初值

  • 静态常数据成员 static const 在类外进行说明和初始化

例:


常引用

当需要对象作为参数时,生成该参数需要调用复制构造函数,效率比较低,用指针做参数,代码会比较不好看,所以用对象的引用做参数void func(A &a)使用对象引用作参数有一定的风险性,若函数中修改了形参a,则实参也跟着变,有时候这可能不是开发者想要的。若不想要对象发生改变,则使用const限定:void func(const A &a)`


例:


相关文章
热点文章
精彩视频
Tags

站点地图 在线访客: 今日访问量: 昨日访问量: 总访问量: