c/c++ static 对象

C语言中static的变量:

1).static局部变量

A、静态局部变量在函数内定义,生存期为整个程序运行期间,但作用域与自动变量相同,只能在定义该变量的函数内使用。退出该函数后, 尽管该变量还继续存在,但不能使用它。
B、对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。

2).static全局变量

全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。但是他们的作用域,非静态全局变量的作用域是整个源程序(多个源文件可以共同使用);而静态全局变量则限制了其作用域, 即只在定义该变量的源文件(.h或.cpp)内有效, 在同一源程序的其它源文件中不能使用它。
关于C语言static变量的理解:

A、若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;

B、若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;

C、静态变量和全局变量放在程序的全局数据区,而不是在堆栈中分配,所以不可能导致堆栈溢出;

D、设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题;

C++语言中static的变量:

1).static局部变量

#include <iostream>
class Test 
{
public:
    Test()
    {
        std::cout << "Constructor is executed\n";
    }
    ~Test()
    {
        std::cout << "Destructor is executed\n";
    }
};
void myfunc()
{
    static Test obj;
} // Object obj is still not destroyed because it is static

int main()
{
    std::cout << "main() starts\n";
    myfunc();    // Destructor will not be called here
    std::cout << "main() terminates\n";
    return 0;
}
输出:
main() starts
Constructor is executed
main() terminates
Destructor is executed 

A、static成员变量设置初值的时候,不受任何权限(public,protected,private)的束缚。但是这里需要解释的是,并不是在任何时候都不受束缚,仅仅在赋初始值的时候不受权限束缚,如果是在中途改变static成员变量的值的话,必须是public类型的才能改变,否则编译错误。

B、这个static变量在初始化后,生存期为整个程序运行期间(在main函数结束后调用析构函数),该静态成员被类的所有对象所共享。即在内存中对所有的对象,只有一份。
例如:对配置文件的类,我们可以在里面定义一个它自身的静态成员对象指针。这样,当我们要使用配置时,只用获取这个指针,就可以进行具体操作。

2).static全局变量

#include <iostream>
class Test
{
public:
    int a;
    Test()
    {
        a = 10;
        std::cout << "Constructor is executed\n";
    }
    ~Test()
    {
        std::cout << "Destructor is executed\n";
    }
};
static Test obj;
int main()
{
    std::cout << "main() starts\n";
    std::cout << obj.a;
    std::cout << "\nmain() terminates\n";
    return 0;
}
输出:
Constructor is executed
main() starts
10
main() terminates
Destructor is executed

A、C++中的全局静态变量和C语言中的全局静态变量作用相同(对象的构造函数在main函数之前就被调用,这就是为什么多个全局static对象互相操作时,会有构造先后顺序的问题,见下文注意点)。

C++中关于静态成员的几点理解:

1、静态数据成员仅仅在初始化时,不受访问权限的约束;

2、静态数据成员最好不要在.h文件中进行声明,而是放在.o文件中声明;

3、静态数据成员被类的所有对象所共享,包括类的派生类的所有对象;——即派生类和基类共享一个静态成员。

4、静态数据成员的类型可是所属类自己,即在一个类中可以声明该类自己的类型的静态成员对象,但是,不可以定义普通的成员对象,(指针可以)

5、在const成员函数中,可以修改static成员变量的值。普通成员变量的值,是不能修改的。

6、static成员函数只能访问static成员,不能访问非static成员,并且static成员函数不能定义为const函数。即不能有CV约束(const
和 voliate约束)

7、静态数据成员可以定义有const约束

lambda 函数中的 static 变量:

lambda 函数本质是一个对象,因此,所有的lambda函数共享同一个static变量。

在c++中使用全局对象,或者全局static对象的注意点

所谓static对象,其寿命从被构造出来直到程序结束为止,因此stack和heap-based对象都不是static对象。这种对象包括global对象, 定义于namespace作用域内的对象, 在classes内、在函数内、以及在file作用域内被声明为static的对象(这么说的话,全局变量也是static变量)。函数内的static对象称为local static对象(因为他对函数而言是local),其他static对象称为non-local static对象。static对象会在程序结束时自动被销毁,即在main()函数结束后调用析构函数。

问题是:如果某编译单元内的某个non-local staitc对象的初始化动作使用了另一个编译单元内的某个non-local static对象,它所用到的对象可能尚未被初始化,因为c++对”定义于不同编译单元内的non-local static对象”的初始化次序并无明确定义。

解决方法:将non-local static对象(包括全局对象,定义在namespace中的对象,以及不是在函数中声明的static对象)变为local static对象,即将 static对象的声明放在函数中。
如下:

class MyClass{...};
MyClass& mc()
{
    static MyClass g_mc;
    return g_mc;
}

这样比直接声明全局的 extern MyClass mc 或者声明 static MyClass mc 要来的好,因为C++保证:函数内的local static对象会在“该函数被调用期间”“首次遇上对象之定义式”时被初始化。所以如果你一“函数调用”(返回一个reference指向local static对象)替换 “直接访问non-local static对象”,你就获得了保证,保证你所获得的那个reference将指向一个已经被初始化的对象。

如果使用static menber:
If you have the class in a header file:

#include "BigImplementationDetail.h"
class PublicInterface {
  public:
    /* ... */
  private:
    static BigImplementationDetail detail_;
};

最好将该静态变量的实现放在匿名的命名空间中,而不是在头文件中:

namespace {
BigImplementationDetail detail_;
}  // namespace

That way, people who don’t use your interface don’t need to know about or care about BigImplementationDetail.

备忘
摘自effective c++
整理格式,转自http://blog.csdn.net/xupan_jsj/article/details/7459108

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值