C++入门:存储类

存储类定义 C++ 程序中变量/函数的范围(可见性)和生命周期。这些说明符放置在它们所修饰的类型之前。下面列出 C++ 程序中可用的存储类:

  • auto

  • register

  • static

  • extern

  • mutable

  • thread_local (C++11)

从 C++ 17 开始,auto 关键字不再是 C++ 存储类说明符,且 register 关键字被弃用。

std::cout << "Count is " << count << std::endl;

在前面的学习中我们看到的输出没有 std::,而这一节出现了上面的代码。

std 是标准库函数使用的命名空间,是 standard(标准)的缩写。

using namespace std ,它声明了命名空间 std,后续如果有未指定命名空间的符号,那么默认使用 std,这样就可以使用 cin、cout、vector 等。

假设你不使用预处理 using namespace std;,就要加上 std::cin 或者 std::cout

cin 用于从控制台获取用户输入,cout 用于将数据输出到控制台。

cin 是输入流对象,cout 是输出流对象,它们分别可以用 >><<,是因为分别在其类中对相应运算符进行了重载。

静态局部变量

在局部变量前,加上关键字static,该变量就被定义成为一个静态局部变量。 我们先举一个静态局部变量的例子,如下:

#include <iostream>

void fn();
int main()
{
    fn();
    fn();
    fn();
}
void fn()
{
    static int  n=10;
    std::cout<<n<<std::endl;
    n++;
}

通常,在函数体内定义了一个变量,每当程序运行到该语句时都会给该局部变量分配栈内存。但随着程序退出函数体,系统就会收回栈内存,局部变量也相应失效。但有时候我们需要在两次调用之间对变量的值进行保存。

通常的想法是定义一个全局变量来实现。但这样一来,变量已经不再属于函数本身了,不再仅受函数的控制,给程序的维护带来不便。

静态局部变量正好可以解决这个问题。静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。

静态局部变量有以下特点:

该变量在全局数据区分配内存;

静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化;

静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0;

它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束;

1.static 修饰类的成员变量

1). 静态成员变量是先于类的对象而存在

2). 这个类的所有对象共用一个静态成员

3). 如果静态成员是公有的,那么可以直接通过类名调用

4). 静态成员数据在声明时候类外初始化

#include <iostream>

using namespace std;
class Data
{
public:
    Data(){}
    ~Data(){}
    void show()
    {
        cout<<this->data<<" "<<number<<endl;
    }

    static void showData()//先于类的对象而存在
    {
        //这方法调用的时候不包含this指针
        cout<<" "<<number<<endl;
    }

private:
    int data;
public:
    static int number; //静态数据在声明时候类外初始化
};
int Data::number=0;//静态成员初始化

int main()
{
    Data::showData();//通过类名直接调用


    Data::number = 100;//通过类名直接使用
    Data d;
    d.show();
    d.showData();//通过对象调用

    cout << "Hello World!" << endl;
    return 0;
}

2.static 修饰类的成员方法

1). 静态成员函数是先于类的对象而存在

2). 可用类名直接调用(公有)

3). 在静态成员函数中没有this指针,所以不能使用非静态成员

const 修饰--常量 ---- const修饰的常量代替宏定义

修饰成员变量

const int data;

const 修饰的成员变量必须在构造方法的参数列表初始化(const static int pdata=10;除外)const 修饰的成员变量不能被修改

修饰成员方法

void showData()const{ }

const 修饰的成员函数中不能修改成员变量,不能调用非 const 修饰的函数

const 相比 #define 的优点:

1.const 常量有数据类型,而 #define 没有,编译器可以对前者进行类型安全检查,而对后者只能进行字符替换,没有安全检查,并且在字符替换时候可能导致意想不到的错误。

  1. 有些集成化的调试工具可以对 const 常量进行调试,但是不能对宏常量进行调试。

hread_local 在跨线程时使用:

eg: A 线程是用来拉取数据的,B 线程是用来更新 UI 的,那么 A在拉去数据后应该通知B线程去更新 UI,因为 A 线程不能更新 UI,此时更新 UI 就应该由 B 线程的 thread_local 去进行(因为只有 B 线程能访问),这样可以防止因为跨线程更新 UI 引起的问题。

1、寄存器存在于CPU中,速度很快,数目有限

存储器就是内存,速度稍慢,但数量很大。

计算机做运算时,必须将数据读入寄存器才能运算。

  1. 存储器包括寄存器,存储器有 ROM 和 RAM

在局部变量前加上“static”关键字,就成了静态局部变量。静态局部变量存放在内存的全局数据区。函数结束时,静态局部变量不会消失,每次该函数调用 时,也不会为其重新分配空间。它始终驻留在全局数据区,直到程序运行结束。静态局部变量的初始化与全局变量类似.如果不为其显式初始化,则C++自动为其 初始化为0。

静态局部变量与全局变量共享全局数据区,但静态局部变量只在定义它的函数中可见。静态局部变量与局部变量在存储位置上不同,使得其存在的时限也不同,导致对这两者操作 的运行结果也不同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灰度少爷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值