c++static关键字

c++的static关键字

一、C语言中的static

static是C语言的关键字,也是C++的关键字,其名为静止的意思,在C语言中有两种主要功能,一是修饰变量,二是修饰函数,其实在C++中也是大同小异的

  1. static修饰变量
    static修饰局部变量,可以改变该变量的存储位置为data段或者bss段(具体取决于变量是否初始化),可以改变变量的生命周期,使之整个程序运行时都有效,同时static只初始化一次,比如在局部反复定义一个被static修饰的变量,仍然只有第一次定义时有效。
  2. static修饰函数
    static修饰函数,在C语言中主要是使之只在当前文件中有效,在多文件编程中,我们不想让其他文件使用我们本文件的函数,就可以对函数使用static关键字来限制。

二、C++中的static

C++中对C语言的语法完全兼容,上面C语言相关特性在C++中仍然适用,那么有什么不同之处呢?
C++引入了面向对象的思想,主要不同体现在类中的static的使用上,在大体上又分为静态成员变量和静态成员函数。

  1. 静态成员变量
    静态成员变量也存储在bss或者data内存段中,一个类的静态成员变量只有一份,被所有类对象共享,我的理解是增加了一个类名字空间的全局变量,因此其生命周期不再依赖于任何对象,与程序的整个生命周期相同,作为类成员,可以通过对象直接访问(当然得有权限),作为静态成员变量,也可以通过类名::静态变量名的方式不经过对象直接访问公开的静态成员变量,需要注意的是,静态成员变量必须在类中声明,类外定义,类外定义时需要加类名的域限定符说明范围
class Base
{
public:
    static int data;//声明
};
int Base::data = 100;//定义,这里不需要加static了

int main()
{
    Base b;
    cout << b.data << endl;//类成员直接调用
    cout << Base::data << endl;//类名调用
    return 0;
}
  1. 静态成员函数
    静态成员函数不依赖于类,它没有隐藏的this指针(普通的成员函数是含有this指针的),因此静态成员函数中无法直接访问普通成员变量和普通成员函数,但是可以直接访问静态成员变量和静态成员函数,作为成员函数,它可以通过类成员直接调用,作为静态成员变量,它可以通过类成员直接访问。
//对象名.静态成员函数名();
//对象名->静态成员函数名();
//类名::静态成员函数名();
#include <iostream>
using namespace std;

class Base
{
    public:
    static int data;//声明
    static void func(void)
    {   
        cout << "static func" << endl;
    }   
};
int Base::data = 100;//定义,这里不需要加static了

int main()
{
        Base b;
        Base* p = new Base;
        b.func();
        p->func();
        Base::func();
        return 0;
}

三、单例模式实现

有了以上的知识,我们可以了解一个名叫单例模式的设计模式,假设我们在创建一个对象时,我们想要该对象有且仅有一个,这样可以省去很多麻烦,在实际的代码世界中也有很多的运用,比如说我们使用Windows下ctrl+shift+esc可以调出任务管理器,但是你再使用同样的方式想要调出另一个任务管理器,却发现怎么也弄不出来,那就是单例模式的体现,其他类似的还有日志管理器,网站访问计数器,线程池,内存池,服务器的连接管理器等等

实现单例模式的原理:

  • 禁止在类外创建类对象,把构造函数、拷贝构造私有化
  • 确保类对象只有一份,在类中定一个静态成员指针变量或类对象
  • 提供一个获取静态类对象、指针的接口,设计静态成员函数用于获取静态类对象、指针

单例模式中又可以分为饿汉模式和懒汉模式:

饿汉模式的单例:

程序运行时就实例化出类对象,不管后期是否用到都会创建出来
优点:不可能被多个线程同时运行时创建多份 (线程安全)
缺点:如果后期使用不到单例对象,浪费了资源,在不使用时也占用内存,实际上造成了内存泄漏

#include <iostream>
using namespace std;

class Base
{
    static Base obj;//静态成员声明
    Base()//私有化构造
    {   

    }   
    Base(const Base& that)//私有化拷贝构造
    {   

    }   
public:
    static Base& getObj(void)
    {   
        return obj;
    }   
    void func(void)
    {   
        cout << "Base func"<<endl;
    }   
};
Base Base:: obj;//静态成员初始化
int main(int argc,const char* argv[])
{
    Base& a = Base::getObj();
    a.func();
    return 0;
}

懒汉模式的单例:
直到真正使用时才创建单例类对象
优点:什么时候用什么时候创建,如果用不到就不会创建,节约了资源
缺点:可能多个线程同时创建,有可能会创建多份单例对象(线程不安全)(线程竞争问题),可以通过加锁解决

#include <iostream>
#include <pthread.h>
using namespace std;

class Base
{   
    static Base *obj;//静态成员声明
    static pthread_mutex_t lock;//保证线程安全
    Base()//私有化构造
    {

    }
    Base(const Base& that)//私有化拷贝构造
    {

    }
public:
    static Base& getObj(void)
    {
        pthread_mutex_lock(&lock);
        if(obj == NULL)
        {
            obj = new Base;
        }
        pthread_mutex_unlock(&lock);
        return *obj;
    }
    void func(void)
    {
        cout << "Base func"<<endl;
    }
};
Base* Base:: obj = NULL;//静态成员初始化
pthread_mutex_t Base::lock = PTHREAD_MUTEX_INITIALIZER;

int main(int argc,const char* argv[])
{
    Base& a = Base::getObj();
    a.func();
    return 0;
}

初学者,如有错误,还望指出,感激不尽

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值