运算符重载
类型转换
其他类型向自定义类型转换
- 只有当类中构造了合适的构造函数时,转换才能成功,被称为隐式类型转换
从自定义类型向其他类型转换
-
是由类型转换函数完成的
operator 目标类型(){ //... }
-
特征:
- 必须是成员函数
-
参数列表无参
- 没有返回值,但必须return返回一个目标类型变量
-
只有一个类型转换函数,自定义类型向其他类型转换时就会自己调用
作用域
- 作用域可以分为类作用域、类名的作用域以及对象的作用域几部分内容
- 类作用域:一个类定义在另一个类里面,这就是嵌套类或者内部类
- 全局作用域:在函数和其他类定义的外部定义的类称为全局类
- 块作用域:在函数里面定义类,范围自然在函数内部
int number=1;
namespace wd
{
int number=20;
class Test{
public:
Test(int num):number(num){}
void print(int number){
cout<<"形参number = "<<number<<endl;
cout<<"数据成员number = "<<this->number<<endl;
cout<<"数据成员number = "<<Test::number<<endl;
cout<<"命名空间number = "<<wd::number<<endl;
cout<<"全局number = "<<::number<<endl;
}
private:
int number;
};
}
//同名变量套娃覆盖:全局(命名空间(类私有数据成员(类成员函数形参)))
int main(){
wd::Test tst(5000);
tst.print(60000);
return 0;
}
单例模式的自动释放
-
单例模式如果后面没有操作其他操作了,即使忘记回收,实际上操作系统会帮我们进行回收
-
valgrind测试代码是否有内存泄漏
-
在线安装:sudo apt install valgrind
-
程序编译时候,添加的-g 选项:
g++ -g -o memcheck memcheck.cpp
-
最常用的命令格式:
valgrind --tool=memcheck --leak-check=full ./memcheck
-
方法1:友元形式
- 将另一个类设为单例的友元
- 可以在另一个类中使用析构函数来自动执行单例的destroy
- 而后实例化另一个类
class AutoRealse;
class Singleton
{
friend AutoRealse;
public:
static Singleton *getInstnce()
{
if(nullptr == _pInstance)
{
_pInstance = new Singleton();
}
return _pInstance;
}
private:
Singleton()
{
cout << "Singleton()" << endl;
}
~Singleton()
{
cout << "~Singleton()" << endl;
}
private:
static Singleton *_pInstance;
};
Singleton *Singleton::_pInstance = nullptr;
class AutoRealse
{
public:
AutoRealse()
{
cout << "AutoRealse()" << endl;
}
~AutoRealse()
{
cout << "~AutoRealse()" << endl;
if(Singleton::_pInstance)
{
delete Singleton::_pInstance;
Singleton::_pInstance = nullptr;
}
}
};
int main(int argc, char **argv)
{
Singleton::getInstnce();
AutoRealse ar;//栈对象
return 0;
}
方法2:内部类+静态数据成员形式
-
将另一个类写在单例里面,用private保护起来
-
记得初始化Singleton::AutoRlease Singleton:: _ar;
class Singleton
{
public:
static Singleton *getInstnce()
{
if(nullptr == _pInstance)
{
_pInstance = new Singleton();
}
return _pInstance;
}
#if 0
static void destroy()
{
if(_pInstance)
{
delete _pInstance;
_pInstance = nullptr;
}
}
#endif
private:
class AutoRealse
{
public:
AutoRealse()
{
cout << "AutoRealse()" << endl;
}
~AutoRealse()
{
cout << "~AutoRealse()" << endl;
if(_pInstance)
{
delete _pInstance;
_pInstance = nullptr;
}
}
};
private:
Singleton()
{
cout << "Singleton()" << endl;
}
~Singleton()
{
cout << "~Singleton()" << endl;
}
private:
static Singleton *_pInstance;
static AutoRealse _ar;
};
Singleton *Singleton::_pInstance = nullptr;
Singleton::AutoRealse Singleton::_ar ;
int main(int argc, char **argv)
{
Singleton::getInstnce();
return 0;
}
方法3:atexit()+饿汉模式方式
- 注册一个函数,当程序正常结束时会被调用
- 头文件stdlib.h
- 注册一次执行一次建议放在getInstance的判空里面
- 多线程环境,因为异步性已不符合单例模式
- 初始化时赋值Singleton *Singleton::_pInstance = getInstance();//饿汉模式
#include <stdlib.h>
#include <iostream>
using std::cout;
using std::endl;
class Singleton
{
public:
static Singleton *getInstnce()
{
if(nullptr == _pInstance)
{
_pInstance = new Singleton();
atexit(destroy);
}
return _pInstance;
}
static void destroy()
{
cout << "void destroy()" << endl;
if(_pInstance)
{
delete _pInstance;
_pInstance = nullptr;
}
}
private:
Singleton()
{
cout << "Singleton()" << endl;
}
~Singleton()
{
cout << "~Singleton()" << endl;
}
private:
static Singleton *_pInstance;
};
/* Singleton *Singleton::_pInstance = nullptr; //饱汉(懒汉)模式*/
Singleton *Singleton::_pInstance = getInstnce();//饿汉模式
int main(int argc, char **argv)
{
Singleton::getInstnce();
Singleton::getInstnce();
return 0;
}
方法4:pthread_once
- 一个进程中多线程条件下,第一次调用这个函数会执行init_routine,而后在相同once_control情况下只会执行一次
- pthread_once(&_once, init);
- POSIX是linux下标准,编译要调用-pthread,不具备跨平台性
- pthread_once_t Singleton::_once=PTHREAD_ONCE_INIT;
#include <stdlib.h>
#include <pthread.h>
#include <iostream>
using std::cout;
using std::endl;
class Singleton
{
public:
static Singleton *getInstnce()
{
pthread_once(&_once, init);
return _pInstance;
}
static void init()
{
_pInstance = new Singleton();
atexit(destroy);
}
static void destroy()
{
cout << "void destroy()" << endl;
if(_pInstance)
{
delete _pInstance;
_pInstance = nullptr;
}
}
private:
Singleton()
{
cout << "Singleton()" << endl;
}
~Singleton()
{
cout << "~Singleton()" << endl;
}
private:
static Singleton *_pInstance;
static pthread_once_t _once;
};
Singleton *Singleton::_pInstance = nullptr; //饱汉(懒汉)模式
/* Singleton *Singleton::_pInstance = getInstnce();//饿汉模式 */
pthread_once_t Singleton::_once = PTHREAD_ONCE_INIT;
int main(int argc, char **argv)
{
Singleton::getInstnce();
Singleton::getInstnce();
return 0;
}