数据的共享和保护


数据的共享和保护

作用域

  • 函数原型作用域:

    void fun(int a); //这里是一个函数原型声明,变量a的作用域就是函数原型作用域,仅在括号之内

  • 局部作用域:

    函数定义时的形参,函数内部声明的变量,以及代码块内的变量,都是局部变量,处于局部作用域。

  • 类作用域:声明在class中的属性或方法

  • 命名空间作用域:声明在命名空间中的内容。

    • 采用using关键字使用命名空间的资源:using namespace spaceName;全部空间中的资源都可直接使用。或者,using spaceName::ResourceName;仅使用该空间中指定的该资源。

    • 命名空间可以嵌套,使用的时候需要连缀使用域操作符::

    • 全局命名空间:全局变量,即声明在指定的namespace之外的全局的资源都属于一个无名的全局命名空间,全局可以直接使用。在函数体内有重复名称的时候,直接用::表示调用全局命名空间的资源,即全局变量。

    • 匿名命名空间:namespace { body }。作用是为了其他源文件不能访问该命名空间中的内容。

    // test unnamed namespace
    namespace {
        int a = 10;
        int b = 20;
    }
    int a = 30;
    void test2() {
        // cout << a << endl;    // 错误,a不知道是匿名空间的还是全局的
        cout << ::a << endl;     // 30
        cout << b << endl;       // 20,匿名空间中的资源相当于static,可直接在本源文件中使用。
    }

生存期

生存期指资源创建到结束的这段时间。

  • 静态生存期:与程序同生死,程序运行阶段都存在的资源,如全局变量。

    • 命名空间作用域中的资源都是静态生存期的。

    • 若在函数中(局部)声明静态的变量,需要用static关键字,

    函数中声明变量用static等同于该变量变成了全局的,且每次调用该函数,该static变量值不会重置。

    函数中static和全局的static关键字作用不同。全局的static是限定该变量的作用域,限定在本代码文件中,不能被其他文件引用,c++不再提倡使用static(提倡在class中用static,全局用匿名namespace达到同样目的)。而函数中的static是改变变量的生存期的,由local变成global。

  • 动态生存期:除了静态(全局)生存期,其他都是动态生存期(局部生存),从声明处到代码块结束。

上述描述没有涉及类的静态成员。

类的静态成员

类的静态成员,属于该类的资源,而不是单属于某一个对象,它可以为该类的所有对象而公用,实现数据共享。最典型的如类的对象个数统计。

静态成员通过static声明。可以通过类名::varName调用。

class中的static变量,仅仅是一个声明,需要在外部重新为它定义(声请内存空间,或者同时赋初值)

class Foo{
private:
    static int count; // 静态数据成员 声明,显然这里用于统计Foo类的对象个数
public:
    Foo(){count++;}
    ~Foo(){count--;}
}
int Foo::count = 0; // 分配空间并赋初值。

同理,还有类的静态函数,或者说静态方法,静态方法不能直接访问非静态属性。

友元

友元实际上就是主动告诉别人,我是你的朋友,你可以使用我的资源。从而打破原有的访问控制规则。

通过friend声明友元关系。

  • 友元函数:可以是一般函数或其他类的成员函数。在本类中声明,但它不属于本类的函数,但是它的函数体内,可以调用本类的资源。
  • 友元类:A类是B类的友元类(在B类中声明friend class A,表示A是我的朋友),则A中所有成员函数都是B的友元函数,则A中函数都可以访问B的受限资源。
  • 原则:
    1. 友元关系不能传递。
    2. 友元关系单向的。
    3. 友元关系不能被继承。

常量

  • 常成员函数:返回类型 方法名(参数列表) const; // 函数原型

    • 在函数定义的时候const也需要带上。
    • 一个常对象只能调用它的常方法。
    • const算是一个函数重载条件。
    • const常成员函数不能修改对象的数据成员。
  • 常数据成员:类的const属性

    • 则类的任何函数都不能修改该常量值。
    • const常数据成员只能通过构造函数的初始化列表进行初始化。
    class A{
      pirvate:
      const int a;
      static const int b;
      public:
      A(int i);
    }
    // 初始化常量成员,构造函数的初始化列表
    A::A(int i) : a(i){ void;}
    // 静态常量成员初始化
    const int A::b = 0;
  • 常引用:const &,常引用的对象不能被修改,常用作函数参数类型,避免栈中创建临时对象,减少开销。

编译预处理命令

tips:将需要分配空间的定义放在源文件中,将不需要分配空间的声明放在头文件中。

预处理器在编译器编译源程序之前工作,可以通过预处理指令制定一些预处理工作。

  • #include
  • #define 定义宏 #undef 删除宏
  • 条件编译:#if #ifdef #ifndef #else #elif #endif
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值