单例模式中的懒汉模式
//懒汉模式
class Singleton
{
public:
static Singleton* getInstance() {
if (instance == nullptr) {
i_mutex.lock();
if (instance == nullptr) {
instance = new Singleton();
}
i_mutex.unlock();
}
return instance;
};
~Singleton() {};
static cleanup() { delete instance; instance = nullptr; };
private:
Singleton() {};
Singleton(const Singleton& s) = delete;
Singleton& operator=(const Singleton& s) = delete;
private:
static Singleton* instance;
static std::mutex i_mutex;
};
Singleton* Singleton::instance = nullptr;
mutex Singleton::i_mutex;
单例模式中的饿汉模式
class SingletonHungry
{
public:
static SingletonHungry* getInstance() { return instance; };
~SingletonHungry() { delete instance; };
private:
SingletonHungry() {};
SingletonHungry(const SingletonHungry& s) = delete;
SingletonHungry& operator=(const SingletonHungry& s) = delete;
private:
static SingletonHungry* instance;
};
SingletonHungry* SingletonHungry::instance = new SingletonHungry();
1、单例模式中,类的构造函数为什么是private的?
权限修饰符private的作用:保证类的构造函数不能出现在类的外部,换句话说,你不能在类的外部,比如在主线程main函数中来直接调用构造函数来构造对象。另一种情况,也是最常见的,我们通常使用关键词public来修饰构造函数,这样的构造函数是直接暴露给类的外部的,类的外部是可以多次调用这样的构造函数来创建多个对象,比如在主线程main函数中多次调用构造函数来创建多个对象。
2、类的构造函数为什么不能使用static关键字?
类的构造函数不能是static的,因为类的构造函数的参数中有一个隐式的指向对象本身的this指针,通过该指针你可以访问内部的成员变量。当你使用static关键字来修饰类的一个成员函数,那么编译器在编译该成员函数时,编译器就不会将隐式的this指针添加到该成员函数的形参的末尾。
对于关键字static的理解
注意,static关键字只作用于当前变量,意思是将当前变量定义在静态存储区。
举个例子:
#include<iostream>
class Test {
public:
int static* si1;//static关键词作用于当前变量,即使这个变量是一个指针变量
int static* si2;
int static* si3;
public:
Test() {
}
void print() {
std::cout << &si1 << ":" << si1 << std::endl;
std::cout << &si2 << ":" << si2 << std::endl;
std::cout << &si3 << ":" << si3 << std::endl;
}
~Test() {
delete si1;
delete si2;
delete si3;
}
};
int* Test::si1 = new int(4);
int* Test::si2 = new int(5);
int* Test::si3 = new int(6);
int static* si4 = new int(7);
static int *pcount = &count;
int main() {
Test test;
test.print();
std::cout << &si4 << ":" << si4 << std::endl;
delete si4;
return 0;
}输出结果展示:
//第一次的输出结果
01006770:010F5E70
0100676C:010F5EA0
01006774:010F5ED0
01006768:010F5CD8
//第二次的输出结果
01006770:00E05E70
0100676C:00E05EA0
01006774:00E05ED0
01006768:00E119C0
通过分析输出结果可以得知:变量si1、si2、si3、si4本身的地址是连续的(68-6C-70-74),所以说这4个指针变量是存放在静态区的,换句话说,关键字static只对这4个指针变量起作用;注意!!!static是只对你定义的变量起作用,尽管你这个变量是一个指针变量(指针变量只是表明你你定义的这个变量是存放地址的,可以进行解引用)。
第二个方面就是对new的理解,从输出结果可以看到,si1、si2、si3、si4保存的对象的地址不是连续的(CD8-E70-EA0-ED0),由此可以得知,通过new创建的对象实际上是在堆区上创建的,返回的地址也就是堆区内存的地址。换句话说,定义在静态存储区的指针变量是不需要你删除的(并且你也无法回收定义在程序静态存储区的指针变量),但是,请注意!!!虽然指针变量是放在静态存储区,但是你的指针变量保存的对象的地址却是通过new的方式在堆区创建的地址,你需要使用关键字delete来回收这块内存。
总而言之,static不具有传递性,staitc关键字只作用于当前定义的变量本身(换句话说,即使你定义的指针变量是存储在静态区的,但这并不意味着该指针指向的对象也是存储在静态区的,也可以是堆区的),new的数量必须和delete的数量完全一致,不然就会出现内存泄漏!!!
1 条评论
华纳圣淘沙公司开户新手教程
零基础学会(183-8890-9465薇-STS5099)
华纳圣淘沙公司开户
华纳圣淘沙公司开户保姆级教程(183-8890-9465薇-STS5099)
一步步教你开通华纳圣淘沙公司账户(183-8890-9465薇-STS5099)
华纳圣淘沙公司开户分步图解
首次开户必看:(183-8890-9465薇-STS5099)
华纳圣淘沙全攻略
华纳圣淘沙公司开户实操手册(183-8890-9465薇-STS5099)
华纳圣淘沙开户流程视频教程
手把手教学:(183-8890-9465薇-STS5099)
华纳圣淘沙公司开户
华纳圣淘沙公司开户完全指南(183-8890-9465薇-STS5099)