那些你不知道的C++的“坑”

2017-10-12  本文已影响0人  会飞的猪cy
#include <iostream>

void func(int i) {
  static int s = i++;
  std::cout << s << std::endl;
}

int main() {
  func(0);
  func(1);
  func(2);
  return 0;
}

单纯的你会以为这段代码输出什么?0,1,2?暂且不管它输出什么,我们再来看下一段代码

#include <iostream>

void func(int i) {
  static int s;
  s = i++;
  std::cout << s << std::endl;
}

int main() {
  func(0);
  func(1);
  func(2);
  return 0;
}

上面两段代码有区别吗?事实上,这两段代码的输出结果完全不同。这两段代码均使用了局部静态变量,C++里面局部静态变量只初始化一次,说到这里有没有似乎明白了什么。第一种写法,由于静态变量s只初始化一次,故func(1),func(2)并没有初始化s,输出0,0,0;第二种写法, 每次调用函数并不是给静态变量初始化,而是赋值,故输出0,1,2;如此的细节,你们注意到没。


  1. 隐藏规则,最重要的一条
    当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性,我们举例子加以说明。
    i.h文件
int i = 9;

main.cpp文件

#include <iostream>
#include "i.h"
int main() {
  std::cout << i << std::endl;
}

i.h文件中的i变量对所有文件都是可见的。如果把int i = 9;改为static int i = 9;就可以发挥它的隐藏功能了,这时如果main.cpp中的main函数中添加i = 1;则输出结果就为1,因为main.cpp中的i隐藏了static i,静态变量i只对i.h文件可见,因而其他文件可以定义相同名字的变量,而不会发生冲突.

  1. 默认初始化为0
    这个同全局变量一样,未初始化的静态变量会初始化为0。因为全局变量也是存放在静态数据区

#include <iostream>

class MyClass{
public:
     MyClass(int a,int b,int c);
     void Get();

private:
    int a,b,c;
    static int sum;//声明静态数据成员
};

int MyClass::sum=0;//定义并初始化静态数据成员

对于非静态数据成员,每个类对象都有自己的拷贝。而静态数据成员被当做是类的成员,无论这个类被定义了多少个,静态数据成员都只有一份拷贝,为该类型的所有对象所共享(包括其派生类)。所以,静态数据成员的值对每个对象都是一样的,它的值可以更新。

因为静态数据成员在全局数据区分配内存,属于本类的所有对象共享,所以它不属于特定的类对象,在没有产生类对象前就可以使用.


与普通的成员函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具有this指针。从这个意义上来说,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,只能调用其他的静态成员函数,如果要访问只能通过对象访问,静态成员函数不可以同时声明为 virtual、const、volatile函数。

上一篇 下一篇

猜你喜欢

热点阅读