C++学习笔记02 static关键字

一、类内static 和 类外(全局)static

  1. class 和 struct 内 (此类或此struct的所有实例公共可见)
  2. class 和 struct 外 (只在当前编译单元可见 xxx.obj)

(1)Main.cpp

#include<iostream>
int s_Variable = 10;
int main(){
    std::cout << s_Variable << std::endl;
}

(2)Static.cpp

  1. static int s_Variable = 8; //类似于class的private变量,➕️static 后属于当前.obj文件的private变量
  2. int s_Variable = 8; //项目全局变量,不仅限于当前.obj文件
static int s_Variable = 8; //✅️
int s_Variable = 8;  //❌️ 

当Static.cpp的 同名变量s_Variable 为 static时,只在当前 编译单元Static.cpp可见,编译通过 ✅️
当为非static时,是全局变量,所有编译单元可见❌️
"int s_Variable" (?s_Variable@@3HA) already defined in Main.obj

1. extern 防止全局(类外)非static变量多处定义

修正方式:
去掉Main.cpp中的 = 10赋值操作,并在前面加extern 关键字, 这被称为:external linkage 或者 external linking

#include<iostream>
extern int s_Variable;
int main(){
    std::cout << s_Variable << std::endl;
}

此时,虽然没有 import Static.cpp,但是仍然能打印出 s_Variable的值

2. 类外(全局)非static变量不可以被多处import

在Header中定义的全局变量(未加static),如果被多个.cpp文件引用,报错。#include的原理是复制粘贴代码,所以被不同的地方定义了多次,报错

Header.h
#pragma once
int a = 10;

//Main.cpp
import "Header.h"

//Static.cpp
import "Header.h"

3. 类内静态属性需要在struct和lclass外声明,方法不需要

#include<iostream>

struct Entity {
    static int x;
    static int y;
    static void print() {
        std::cout << x << " , " << y << std::endl;
    }
};

//struct 和 class 静态属性需要在struct 和 class 外声明,否则报错,而 静态方法则不需要在类外声明
int Entity::x;
int Entity::y;

int main() {
    Entity a;
    Entity::x = 3;
    Entity::y = 4;

    //Entity b = { 5, 6 };
    Entity b;
    Entity::x = 5;
    Entity::y = 6;

    Entity::print();
    Entity::print();

    std::cin.get();
}

二、Local static

1. 局部static变量示例

局部静态变量,可以在方法里,可以在if else while 分支里,
生命周期和类中static变量的生命周期一致,只是使用的scope被局限了

#include<iostream>

void Function() {
    static int i = 0;
    i++;
    std::cout << i << std::endl;
}
int main() {
    Function();
    Function();
    Function();
    Function();
    std::cin.get();
}

2. 单例模式类作用域静态变量实现

#include<iostream>
//使用全局静态变量实现单例
class Singleton {
private:
    static Singleton* s_singleton;
public:
    static Singleton& getInstance() {
        return *s_singleton;
    }
    void print() {
        std::cout << "hello world" << std::endl;
    }
};
//必须写,否则编译报错
Singleton* Singleton::s_singleton = nullptr;

int main() {
    Singleton s = Singleton::getInstance();
    s.print();
    std::cin.get();
}

3. 单例模式本地作用域静态变量实现

#include<iostream>
class Singleton {
public:
    static Singleton& getInstance() {
        static Singleton s_singleton;
        return s_singleton;
    }
    void print() {
        std::cout << "hello world" << std::endl;
    }
};

int main() {
    Singleton s = Singleton::getInstance();
    s.print();
    std::cin.get();
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 自动引用计数1.首先是生成对象,持有对象,释放对象,摧毁对象的概念: 生成并持有对象: alloc/copy/ne...
    萨缪阅读 2,563评论 0 6
  • static关键字可用于声明变量、函数、类数据成员和类函数。其主要影响着它们的生命周期、作用域和存储位置。 sta...
    艰默阅读 1,423评论 0 1
  • const: 所修饰的对象或变量不能改变,修饰函数时,该函数不能修改在函数外面声明的变量,也不能调用任何非cons...
    Catcola阅读 3,443评论 0 0
  • 前言 最近在学习C++,找到了浙大的翁凯老师的课,感觉翁老师讲的是真的好,真心感谢翁老师。这篇笔记是跟着他的课记下...
    Come_Back_Cai阅读 3,474评论 0 6
  • ^函数重载的匹配: 当函数名被重载后,函数的匹配过程:首先寻找能精确匹配的函数,如果未能精确匹配,则尝试...
    鲁大帅阅读 4,726评论 0 1

友情链接更多精彩内容