c++中的static修饰符示例详解
前言
本文主要给大家介绍了关于c++中static修饰符的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。
下面一段是引用自effective c++ 中的一句话:
所谓的static对象,其寿命是从构造出来到程序结束为止(以下文章不再赘诉)。因此stack和heap-base对象都被排除。这种对象包括global对象,定义于namespace作用域内的对象,在classes内,在函数内,以及在file作用域内被声明为static的对象。
所以static在c++中可以存在在一下几种情况:
1.存在于全局作用域中的静态变量
//全局可访问,在内存中只有一份拷贝,可被很多函数修改。 #include <iostream> static int i = 1; //作用域是整个file void get(){ std::cout << "in func , the i is " << i << std::endl; } int main(){ std::cout << "the i is " << i << std::endl; get(); return 0; }
2.存在于函数当中的静态变量
// 只能在这个函数中才能被调用。 // 函数调用结束后,一般局部变量都被回收了,静态变量还存在 #include <iostream> void get(){ static int i = 1; std::cout << "the i is " << i << std::endl; i++; } int main(){ get(); // i = 1 get(); // i = 2 std::cout << "the i is " << i << std::endl; // 这种是错误的 return 0; }
3.存在于类的成员变量中的静态变量
//其实原理跟函数中的静态变量类似,类实例化出来的对象被销毁后, // 但是类变量(静态成员变量)还是存在在内存中的 #include <iostream> class Widget{ public: Widget(int i){ a = i; } void get(); private: static int a; // 声明静态变量 }; int Widget::a = 1; // 由于是类变量不是属于专属于一个对象的,被所有对象共享 // 所以需要在类外定义 void Widget::get(){ std::cout << "the a is " << a++ << std::endl; } int main(){ Widget w(1); w.get(); // a = 1 w.get(); // a = 2 return 0; }
4.存在于类中成员函数中的静态变量
#include <iostream> class widget{ public: widget(){} void get(); }; void widget::get(){ static int i = 1; //成员函数中的静态变量的作用域范围跟普通局部变量的作用域范围是一样的 std::cout << "in func, the i is " << i++ << std::endl; } int main(int argc, char const* argv[]) { widget w1; w1.get(); // in func, the i is 1 widget w2; w2.get(); // in func, the i is 2 return 0; }
5.存在于命令空间中的静态变量
#include <iostream> namespace Widget { static int i = 1; // 在该命名空间可用 void get(){ std::cout << "the i is " << i++ << std::endl; } } // namespace Widget int main (){ using namespace Widget; get(); //the i is 1 get(); // the i is 2 return 0; }
6.存在于全局作用域的静态函数
// 其实跟一般的函数差不多, // 但是它将该函数的链接属性限制为内链接, //只能在本编译单元中使用(也就是本文件), //不能被extern等在外部文件中引用 static void get(){ std::cout << "this is staic global func" << std::endl; } int main(){ get(); get(); return 0; }
7.存在于类中的静态函数
#include <iostream> class Widget{ public: Widget(int i){ a = i; } static void get(); // 声明静态函数 private: static int a; int b; }; int Widget::a = 1; void Widget::get(){ std::cout << b << std::endl; //这是错误的,因为静态函数和静态变量直接能够 // Widget::get()调用,不需要实例化,所以不能 // 调用只能实例化才能初始化的成员变量。 std::cout << a << std::endl; //ok } int main(){ Widget w(1); w.get(); return 0; }
总结:
不管是什么静态变量,它的lifetime是从他被构造出来到程序结束为止。
static类型的变量跟其他普通的变量的不同在于在内存中的存在形式不同,例如存在于函数中的局部变量,每当调用一次函数,就会产生一个局部变量,而存在于函数中的静态变量只在该函数第一次被调用时被初始化,然后,然后在内存只保有一份拷贝
补充
链接属性分为三种:
1. 内链接
2. 外链接
内链接:
static修饰的函数和变量 和 const 修饰的变量(不包含extern)都是内链接,只能在本文件中使用,即使别的文件定义了相同的变量名也不要紧。
外链接:
没有用static修饰的全局变量或者函数,都是可以作为外链接用extern修饰的全局变量或者函数,也是作为外部链接。还有一个 extern const int i = 1;这也是外部链接,因为extern的作用会覆盖掉const使它成为外链接。
还有一类:局部变量,它的lifetime只是在函数执行期间,所以是没有链接属性的。
常成员函数是不能修改类中成员变量的,但是静态成员变量是类变量,所以可以修改
#include <iostream> class Widget{ public: Widget(int i){ b = i; } void set() const; private: static int a; int b; }; int Widget::a = 1; void Widget::set() const{ a++; //这是对的,因为是静态成员变量是类变量 b++; //错误的,普通成员变量是不能被常函数改变的。 }
总结
以上就是这篇文章的全部内容了,本文还有许多不足,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。
上一篇:C++编程之CString、string与、char数组的转换
栏 目:C语言
本文标题:c++中的static修饰符示例详解
本文地址:https://www.xiuzhanwang.com/a1/Cyuyan/1093.html
您可能感兴趣的文章
- 04-02c语言没有round函数 round c语言
- 01-10深入理解C++中常见的关键字含义
- 01-10使用C++实现全排列算法的方法详解
- 01-10深入Main函数中的参数argc,argv的使用详解
- 01-10c++中inline的用法分析
- 01-10如何寻找数组中的第二大数
- 01-10用C++实现DBSCAN聚类算法
- 01-10全排列算法的非递归实现与递归实现的方法(C++)
- 01-10C++大数模板(推荐)
- 01-10浅谈C/C++中的static与extern关键字的使用详解
阅读排行
本栏相关
- 04-02c语言函数调用后清空内存 c语言调用
- 04-02func函数+在C语言 func函数在c语言中
- 04-02c语言的正则匹配函数 c语言正则表达
- 04-02c语言用函数写分段 用c语言表示分段
- 04-02c语言中对数函数的表达式 c语言中对
- 04-02c语言编写函数冒泡排序 c语言冒泡排
- 04-02c语言没有round函数 round c语言
- 04-02c语言分段函数怎么求 用c语言求分段
- 04-02C语言中怎么打出三角函数 c语言中怎
- 04-02c语言调用函数求fibo C语言调用函数求
随机阅读
- 01-11ajax实现页面的局部加载
- 08-05dedecms(织梦)副栏目数量限制代码修改
- 08-05织梦dedecms什么时候用栏目交叉功能?
- 08-05DEDE织梦data目录下的sessions文件夹有什
- 01-10C#中split用法实例总结
- 04-02jquery与jsp,用jquery
- 01-10delphi制作wav文件的方法
- 01-10SublimeText编译C开发环境设置
- 01-10使用C语言求解扑克牌的顺子及n个骰子
- 01-11Mac OSX 打开原生自带读写NTFS功能(图文