Linux/C++系统编程 day11

运算符重载

类型转换

其他类型向自定义类型转换

  • 只有当类中构造了合适的构造函数时,转换才能成功,被称为隐式类型转换

从自定义类型向其他类型转换

  • 是由类型转换函数完成的

    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保护起来

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OLLz59Q2-1610592442317)(\image-20210113111914941.png)]

  • 记得初始化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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值