[cpp deep dive] 一些奇怪的关键字_不那么奇怪的s

2016-07-23  本文已影响145人  Quasars

个人理解,如果有误请及时指出,我将非常感谢!
还是从一个题目开始吧~

step 0. static变量的存放位置 - 静态存储区

我整理如下(已更新)


静态/动态存储区.png
  1 #include "common.h"                                                                                                                                                                        
  2 int g_uninitial;                                                                
  3 int g_uni[1024];                                                                
  4                                                                                 
  5 int g_initial_d = 1000;                                                         
  6                                                                                 
  7 int main()                                                                      
  8 {                                                                               
  9     static int local_static_var = 100;                                          
 10     static int local_static_un_var;                                             
 11     int stack_var = 100;                                                        
 12     const int ss = 100;                                                         
 13                                                                                 
 14     printf("constant var          -  %p\n", &ss);                               
 15     printf("local var             -  %p\n", &stack_var);                        
 16                                                                                 
 17     printf("lo_sta_uninit(.bss)   -  %p (value %d)\n", &local_static_un_var, local_static_un_var);
 18     printf("global_uninited(.bss) -  %p (value %d)\n", &g_uninitial, g_uninitial);
 19                                                                                 
 20                                                                                 
 21     printf("global_inited(.data)  -  %p\n", &g_initial_d);                      
 22     printf("local_static(.data)   -  %p\n", &local_static_var);                 
 23     printf("constant              -  %p\n", "abcd");                            
 24     printf("MAIN's addr(.text)    -  %p\n", main);                              
 25                                                                                 
 26     return 0;                                                                   
 27 }

结果输出.

work@vm1:~/share/toys/CSE274.me/02_Cpp_Intro$ ./test
constant var          -  0x7ffc9760ee6c  <--------所以const变量本身还是位于堆栈内部,const仅仅是个只读标记而已.
local var             -  0x7ffc9760ee68
lo_sta_uninit(.bss)   -  0x6020a4 (value 0) 
global_uninited(.bss) -  0x601080 (value 0)  <------至于谁高谁低就需要了解装入/分配机制了
global_inited(.data)  -  0x601058
local_static(.data)   -  0x60105c
constant              -  0x400982 <-------------字符串常量,位于main程序所在位置上面一点
MAIN's addr(.text)    -  0x40070d
code(代码贴图差评!@!!)
work@vm1:~/share/toys/CSE274.me/02_Cpp_Intro$ ./test
0 0 0 0 0 0 0 0 16 66 80 11 -128 52 7 -16 32 68 -112 0 -126 84 11 113 48 64 -48 27 -125 116 15 -16 64 72 17 35 -124 -108 0 114 80 74 81 43 -128 -76 23 -14 96 76 -112 0 -122 -44 27 115 112 64 -47 59 -121 -12 31 -16 -128 80 18 67 -120 20 0 116 -112 82 82 75 -128 53 39 -12 -96 84 -112 0 -118 85 43 117 -80 64 -46 91 -117 117 47 -16 -64 88 19 99 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

step 1. C中的static

#include "common.h"

void functest(){
    static int x = 0;
    x++;
    cout<<x<<endl;
}

int main()
{
    functest();
    functest();
    return 0;
}

输出

work@vm1:~/share/toys/CSE274.me/02_Cpp_Intro$ ./test
1
2

step 2. 面向对象中的static. 如何使用.

  1 #include "common.h"                                                                                                                                                                        
  2 int g_uninitial;                                                                
  3 int g_uni[1024];                                                                
  4                                                                                 
  5 int g_initial_d = 1000;                                                         
  6 class base{                                                                     
  7     public:                                                                     
  8         static int ss1;                                                         
  9         static double ss2;                                                      
 10         static void func();                                                     
 11 };                                                                              
 12 int base::ss1;                                                                  
 13 double base::ss2 = 100;                                                         
 14                                                                                 
 15 int main()                                                                      
 16 {                                                                               
 17     static int local_static_var = 100;                                          
 18     static int local_static_un_var;                                             
 19     int stack_var = 100;                                                        
 20     const int ss = 100;                                                         
 21                                                                                 
 22     printf("constant var          -  %p\n", &ss);                               
 23     printf("local var             -  %p\n", &stack_var);                        
 24                                                                                 
 25     printf("global_uninited(.bss) -  %p (value %d)\n", &g_uninitial, g_uninitial);
 26     printf("lo_sta_uninit(.bss)   -  %p (value %d)\n", &local_static_un_var, local_static_un_var);
 27     printf("base::ss1             -  %p (value %d)\n", &base::ss1, base::ss1);  
 28                                                                                 
 29     printf("global_inited(.data)  -  %p\n", &g_initial_d);                      
 30     printf("local_static(.data)   -  %p\n", &local_static_var);                 
 31     printf("base::ss2             -  %p\n", &base::ss2);                        
 32                                                                                 
 33     printf("constant              -  %p\n", "abcd");
 34     printf("MAIN's addr(.text)    -  %p\n", main);                              
 35                                                                                 
 36     printf("sizeof(base)  - %ld\n", sizeof(base));                              
 37     return 0;                                                                   
 38 }   

输出

work@vm1:~/share/toys/CSE274.me/02_Cpp_Intro$ ./test
constant var          -  0x7fff562b87dc
local var             -  0x7fff562b87d8
global_uninited(.bss) -  0x6010a0 (value 0)
lo_sta_uninit(.bss)   -  0x6020c8 (value 0)
base::ss1             -  0x6020c0 (value 0)
global_inited(.data)  -  0x601058
local_static(.data)   -  0x601068
base::ss2             -  0x601060
constant              -  0x400a17
MAIN's addr(.text)    -  0x40070d
sizeof(base)  - 1

附4:

(扩展上面的代码)
#include "common.h"
int g_uninitial;
int g_uni[1024];

int g_initial_d = 1000;
class base{
    public:
        static int ss1;
        static double ss2;
        //virtual static void func2(double k); //error: member ‘func’ cannot be declared both virtual and static.........(4)
        static void func(double k); 
        static void func(int k);
        int out(){//成员函数也不占类的大小.........(2)
            ____("out----");
            ss1++;
            cout<<ss1<<endl;
            func(ss1);          
        }
    private:
        int kk;
};
int base::ss1;
double base::ss2 = 100.2;
void base::func(double k){
    //cout<<kk<<endl; error: invalid use of member ‘base::kk’ in static member function (3)
    ____("double func---");
    cout<<k<<endl;
    cout<<ss2<<endl;
}
void base::func(int kk){
    ____("int func---");
    cout<<kk<<endl;//局部同名变量(参数)
    cout<<ss1<<endl;
}



int main()
{
    static int local_static_var = 100;
    static int local_static_un_var;
    int stack_var = 100;
    const int ss = 100;
    
    printf("constant var          -  %p\n", &ss);
    printf("local var             -  %p\n", &stack_var);
    
    printf("global_uninited(.bss) -  %p (value %d)\n", &g_uninitial, g_uninitial);
    printf("lo_sta_uninit(.bss)   -  %p (value %d)\n", &local_static_un_var, local_static_un_var);
    printf("base::ss1             -  %p (value %d)\n", &base::ss1, base::ss1);
    
    printf("global_inited(.data)  -  %p\n", &g_initial_d);
    printf("local_static(.data)   -  %p\n", &local_static_var);
    printf("base::ss2             -  %p\n", &base::ss2);
    
    printf("constant              -  %p\n", "abcd");
    printf("MAIN's addr(.text)    -  %p\n", main);

    printf("sizeof(base)  - %ld\n", sizeof(base));
    ____("----------");
    
    
    base::func(1);
    base::func((double)2);  //overload not override
    //base::out();  error: cannot call member function ‘int base::out()’ without object base::out();............(1)
    
    ____("-----------");
    base bb1;
    bb1.out();
    
    base bb2;
    bb2.out();
    
    return 0;
}

输出

constant var          -  0x7ffdb0b98e4c
local var             -  0x7ffdb0b98e48
global_uninited(.bss) -  0x6021c0 (value 0)
lo_sta_uninit(.bss)   -  0x6031e8 (value 0)
base::ss1             -  0x6031e0 (value 0)
global_inited(.data)  -  0x602080
local_static(.data)   -  0x602090
base::ss2             -  0x602088
constant              -  0x400d77
MAIN's addr(.text)    -  0x4009b4
sizeof(base)  - 4
----------
int func---
1
0
double func---
2
100.2
-----------
out----
1
int func---
1
1
out----
2
int func---
2
2

step 3. 如何应用到实际工程中

Ref:

  • <a href = http://blog.csdn.net/crayondeng/article/details/24853471>单例模式的探究</a>

归纳一下(黑字是我的补充):
上面的链接中给的一些示例:

  1. 单例模式 != 全静态函数(失去了多态性)
  2. 单例模式的饿汉模式(运行时立刻执行初始化,m_*是个本类类型,本类静态成员)
  1. 单例模式的懒汉模式(改进版)(当引用对象时才进行初始化,m_*是个本类类型指针,getInstance()函数的局部静态变量)
  1. 单例模式的代理模式(通过一个静态嵌套类成员来实现)

step 3. 按上面的建议实现一个单例模式 并在多线程环境中测试

由于工程经验尚不是很多,4我就暂时不考虑,先来个懒汉模式 + 双检锁(DCL)吧.
值得一提的是第二个Ref材料中说明了一个问题,就是static静态成员指针可能被编译器优化(主要是执行顺序的问题),导致一些情况下运行不正常,需要增加volatile关键字.(我先不管那么多)

关于执行顺序主要有2种办法:(目前所知)

1.内存栅栏

2.volatile关键字(需要把volatile搞得遍地都是..)

遗留的问题有:

上一篇下一篇

猜你喜欢

热点阅读