作用域&&生命周期
-
C++ 中的作用域(scope)指的是变量、函数或其他标识符的可见和可访问的范围。
-
生命周期(Lifetime)指的是变量或对象存在的时间段。它开始于变量或对象的创建(定义)时刻,结束于其被销毁的时刻。
-
作用域:通过其声明的位置来确定。
-
全局作用域:定义在(类 / 函数 )外部的变量 || 声明/不先声明直接定义在 (类 / 函数 )外部的函数 || 类,整个程序中都可以访问,不同文件中需要,extern type name,访问。生命周期:整个程序
-
文件作用域:static,将全局变量/函数 作用域限制在当前文件中,对其他文件不可见。生命周期:整个程序
-
命名空间作用域:在命名空间定义的,通过作用域解析运算符访问。在作用域外新增一个命名空间作用域,并不会影响对象的本身链接性 / 生命周期。其实还是当作普通的作用域看。
-
类作用域:在类中定义的 成员变量 || 成员函数声明 || 内联函数,可以通过创建类的对象或引用来访问,作用域:类的私有成员只能在类的内部访问,而公有成员可以在类的外部通过对象访问。生命周期:与类的实例(对象)相关(类对象的生命周期,取决于构造(),析构())
-
函数作用域(局部作用域):函数的参数和在函数内部定义的 变量 / 形参,作用域函数,这能在函数内部访问。生命周期:局部
-
代码块作用域(局部作用域){}内定义,作用域块,这能在块内部访问。生命周期:局部
-
变量分类 && 作用域 && 生命周期:
-
全局变量、全局作用域,生命周期:整个程序
-
全局静态变量、文件作用域,生命周期:整个程序
-
局部变量:局部作用域,生命周期:局部
-
局部静态变量:局部作用域,生命周期:整个程序
嵌套的作用域:
-
嵌套的作用域内(全局&&局部):内层作用域中的变量将覆盖外层作用域中的变量。同名的变量将引用内层作用域中的变量。当离开内层作用域时,外层作用域中的变量将再次可见。
函数分类 && 作用域 && 生命周期:
-
全局函数:全局作用域,生命周期:整个程序
-
成员函数:类作用域,生命周期:与所属对象相关联。
链接性 && extern:
-
external,外部链接属性。全局作用域,对整个程序都是可见的,包括命名空间作用域 中全局作用域的变量
-
非常量全局变量和(除成员函数以外的函数)均默认为外部链接的,包括命名空间中定义的
-
- internal,内部链接属性。文件作用域,其他源文件中不可见
- const对象,constexpr对象,命令空间内的静态对象
- none,类 / 局部 / 块 作用域 仅在定义的位置可见
- 在类中、函数体和代码块中 声明的变量默认是具有none链接属性。它和internal一样只在当前作用域可见。
- extern仅可以声明外部链接属性的变量 / 函数 / 类
关键字static
- static修饰全局变量,作用域限制为文件,生命周期:整个程序。修饰局部变量时,作用域局部,生命周期:整个程序。
- static修饰成员变量或函数,作用域为类
- 普通成员函数可以访问static的变量,静态成员函数只能访问静态成员变量,
this
指针指向调用对象的起始地址:普通成员函数通过this
指针,可以访问对象的非静态成员变量。而静态成员函数静态成员函数不属于任何对象,没有this
指针,因此不能直接访问非静态成员变量。
const:
- const将全局变量作用域限制为文件,但可以extern到其他文件。
- 限定参数:函数中不能修改该参数
- 限定成员函数的修改:修饰成员函数,该函数不能修改其类的成员变量
- 限定返回值特别时返回值为指针或引用时,不能用返回值来改变返回值所指或所引用的变量
命名空间:
- 为什么使用:不同程序员开发不同模块,使用相同命名,那么发生定义冲突,为了防止命名冲突,将全局作用域划分为不同的区域
- 注意定义问题:同一个项目不同文件可以包含相同命名空间,但是内部的成员需要不同
- 注意:如果定义并使用两个相同成员,在编译器会发生重定义错误,如果不使用,仅会在运行时报错
内存分配方式:
- 静态分配(静态存储区),自动分配(栈),动态分配(堆)
动态内存:
- 利用指针通过new(为对象开辟内存) 运算符指向对象地址,提供了灵活的方式来管理对象和变量的生命周期,手动创建和销毁delete(释放指针指向地址对应的内存)对象。动态分配的变量的生存期不受其作用域的限制。
多重 包含 / 定义错误:参考
- c++将代码分为文件进行编译,现在彻底理解一下
- 编译和链接:编译阶段是针对一个一个文件来说的,a.h,a.cpp编译为一个a.o,而链接则是针对一个工程所有的.o(.obj)文件而言,链接Link为c组成一个可执行文件
- #include:拷贝文件,在编译阶段,a.h,a.cpp如果#include "b.h",相当于把b.h拷贝到a文件中,编译为一个a.o。
- 重复包含:
- 当一个文件重复include同一个文件,会发生重复包含错误,通过#ifndef,#define,#endif或者#pragma once(微软编译器独有的,不支持跨平台)保证了,同一个文件不会被包含多次。
- 注意:这类防止重复包含问题的,并不会解决重复定义错误
- 重复定义:
- 头文件中不要定义变量,仅extern变量:当h文件定义一个变量/ 函数 / 类,不同cpp去include这个文件,编译阶段没有问题,但是链接时会重定义错误。如果仅声明,声明多次是没问题的。
- 当非include的问题:对于外部链接性的变量或函数,都不要定义同名的,在链接时会出现错误,对于文件作用域的没问题
- 为什么h中的class没有重定义问题:因为仅仅是类声明
//变量
int x;//定义 + 声明
extern int x;//仅声明
//函数
void fun();//声明
void fun(){};//声明
void fun(){}//定义(后面无;)
//类 / 结构体
class A {//类声明
public:
//定义:成员变量 / 函数
private:
};
A a;//定义
标签:文件,生命周期,变量,作用域,定义,c++,链接,函数
From: https://blog.csdn.net/sengyongan/article/details/139872019