5_数据的共享与保护

数据的共享与保护

标志符的作用域和可见性

作用域

  • 函数原型作用域:函数形参表括号
  • 局部作用域(块作用域):函数体或大括号,函数的形参
  • 类作用域:类体和成员函数体
  • 文件作用域:开始于声明点,结束于文件尾
  • 命名空间作用域
#include <iostream>
using namespace std;

int i = 0; //全局变量,文件作用域 

int main(){
    i= 5;
    {
        int i;  //局部变量,局部作用域
        i = 7;
        cout << i << endl; 
    } 
    cout << i << endl;
    return 0;
}

对象的生存周期

  • 静态生存期:整个程序运行期间都存在,static修饰,未初始化默认为0
  • 动态生存期:结束于作用域尾
#include <iostream>
using namespace std;

int i = 0; //全局变量,文件作用域 
void other(){
    static int a = 1;  //静态局部变量 
    int c = 10;       //局部变量,动态生存期
    a += 2;
    i +=32;
    c +=5; 
    cout << "i: " << i << " a: " << a << " c: " << c << endl;
}

int main(){
    other();
    other();
    return 0;
}

类的静态成员

类的静态数据成员

  • static修饰,为该类的所有对象共享,具有静态生存期
  • 必须在类外定义和初始化,用 :: 来指明所属的类

类的静态函数成员

  • 一般只用于处理类的静态数据成员,不处理具体某个对象的数据。
#include <iostream>
using namespace std;

class Point{
    public:
        Point(int x=0, int y=0):x(x), y(y){
            count++;
        }
        Point(const Point& p){  //复制构造函数 
            x = p.x; y = p.y; count++; 
        }
        ~Point(){       //析构函数 
            count--;
        }
        int getX(){return x;}
        int getY(){return y;} 
        static void showCount(){    //静态函数成员 
            cout << "Object count: " << count << endl;
        }
    private:
        int x, y;
        static int count;   //静态数据成员声明 
};

int Point::count = 0;   //静态数据成员定义和初始化,使用类名限定 

int main(){
    Point::showCount(); //可以直接调用,不需要通过对象调用 
    Point a(4, 5);
    cout << a.getX() << a.getY() << endl;
    a.showCount();     //也可以通过对象调用

    Point b(a);
    cout << b.getX() << b.getY() << endl;
    Point::showCount();
    return 0;
}

友元

  • 友元模块可以访问到另一个模块中被隐藏的信息
  • 关键字 friend 修饰,可以访问private 和 protected成员
  • 在封装和快速性达到平衡

友元函数

#include <iostream>
#include <cmath>
using namespace std;

class Point{
    public:
        Point(int x=0, int y=0):x(x), y(y){
        }
        int getX(){return x;}
        int getY(){return y;} 
        friend double dist(const Point& a, const Point& b){   //友元函数 
            double x = a.x - b.x;  
            double y = a.y - b.y;
            return static_cast<float>(sqrt(x*x+y*y));
        } 
    private:
        int x, y;
}; 

int main(){
    Point p1(1, 5), p2(1,2);
    cout << dist(p1, p2) << endl;
    return 0;
}

友元类

  • 若一个类为另一个类的友元,则此类的所有成员都能访问对方类的私有成员
  • 友元关系是单向的

image-20200711150004819

共享数据的保护

  • 关键字 const 修饰

常对象

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

常成员函数

  • 返回类型 函数名(参数表) const

  • 不更新对象的数据成员

  • 通过常对象只能调用它的常成员函数,非常对象也可以调用它的常成员函数

  • 可以用来区分重载函数

#include <iostream>
#include <cmath>
using namespace std;

class Point{
    public:
        Point(int x=0, int y=0):x(x), y(y){
        }
        int getX(){return x;}
        int getY(){return y;} 
        void print();
        void print() const; //常成员函数 
    private:
        int x, y;
}; 

void Point::print(){
    cout << x << y << endl;
}

void Point::print() const{
    cout << x << y << endl;
}

int main(){
    Point p1(1, 5);
    p1.print();  //调用void print() 

    const Point p2(2, 4);
    p2.print();  //调用void print() const 
    return 0;
}

常数据成员

  • 只能在初始化的时候赋值,其他时候不可以改变其值
#include <iostream>
#include <cmath>
using namespace std;

class A{
    public:
        A(int i);
        void print();
    private:
        const int a;    // 常数据成员的声明 
        static const int b;  //静态常数据成员的声明 
};

const int A::b = 10;  // 静态常数据成员初始化 
A::A(int i):a(i){}   //常数据成员通过列表初始化,不能通过函数体初始化 

void A::print(){
    cout << a << b << endl;
}

int main(){
    A a1(100), a2(0);
    a1.print();
    a2.print(); 
    return 0;
}

常引用

  • 不能通过常引用修改原来的值
  • 非常安全

多文件结构与预编译命令

多文件结构

  • 类声明文件(.h文件)
  • 类实现文件(.cpp文件)
  • 类的使用文件(main所在的.cpp文件)

编译与链接

image-20200711160124414

//类的定义
class Point{
    public:
        Point(int x=0, int y=0):x(x), y(y){
            count++;
        }
        Point(const Point& p); //复制构造函数
        ~Point(){       //析构函数 
            count--;
        }
        int getX() const{return x;}
        int getY() const{return y;} 
        static void showCount();  //静态函数成员
    private:
        int x, y;
        static int count;   //静态数据成员声明 
};

//类的实现
#include "point.h"
#include <iostream>
using namespace std;

int Point::count = 0;  //初始化静态数据成员

Point::Point(const Point& p):x(p.x), y(p.y){
    count++;
} 

void Point::showCount(){
    cout << "Object count: " << count << endl;
}

//主函数文件
#include <iostream>
#include "point.h" 
using namespace std;

int main(){
    Point a(4, 5);
    cout << a.getX() << a.getY() << endl;
    Point::showCount();

    Point b(a);
    cout << b.getX() << b.getY() << endl;
    b.showCount();
    return 0;
}

外部变量与函数

  • 外部变量:文件作用域中定义的变量,默认情况下为外部变量;若需在其他文件中使用,则使用extern关键字修饰

  • 外部函数:类定义之外的函数具有文件作用域,若需在其他文件使用只需extern声明一下即可

  • 在匿名空间中定义的变量和函数不会暴露给其他单元

    namespace {
        int n;
        void f(){
            n++;
        }
    }
    
    

编译预处理命令

  • include:将一个源文件插入到当前源文件中该点处

    • 自定义的.h文件在include时用 " ",会现在当前工作目录找,然后再到系统目录找;而系统.h文件使用 < >,直接到系统目录找
  • define:宏定义指令

    • 定义符号常量,可以用const取代
    • 定义带参数宏,可以用内联函数取代
  • undef:删除#define定义的宏

  • if 和 #endif:选择编译

    #if 常量表达式
        程序正文1   //当常量表达式非零时编译
    #else
        程序正文2
    #endif
    
    
  • ifdef 和ifndef:选择编译,一般在头文件中使用;避免多次编译

    #ifdef 标志符
        程序段1   //当标识符未被定义过则编译
    #else
        程序段2
    #endif#
    
    

原文链接: https://www.cnblogs.com/huanxifan/p/13311382.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    5_数据的共享与保护

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/366978

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 下午5:19
下一篇 2023年3月2日 下午5:20

相关推荐