C++学习笔记08

类型转换

构造函数:其他数据类型——>自定义数据类型
类型转换函数:自定义数据类型——>其他数据类型
但一般情况下不要使用

类型转换函数特点
  • 是成员函数
  • 没有返回值类型
  • 在函数体内以传值形式返回一个目标类型的变量(对象)

PIMPL设计模式

简介

是一种常用的用来对“类的接口和实现”进行解耦的方法,以避免在头文件中暴露私有细节。但PIMPL并非严格意义上的设计模式,可看作是桥接设计模式的一种特例。

作用
  • 实现信息隐藏
  • 降低编译依赖
  • 以最小代价完成库的平滑升级
示例
Line.h

#pragma once
#include <iostream>
using namespace std;
class Line
{
public:
    Line();
    Line(int,int,int,int);
    ~Line();
    void printLine();
private:
    class LinePimpl;
    LinePimpl *_pimpl;
};

LinePimpl.cc
#include "Line.h"

class Line::LinePimpl
{
    //定义点类
    class Point
    {
    public:
        Point(int x,int y)
        : _ix(x), _iy(y)
        {
            cout << "Point::Point(int x, int y)" << endl;
        }
        ~Point()
        {
            cout << "Point::~Point()" << endl;
        }
        void printPoint()
        {
            cout << "(" << _ix << ", " << _iy << ")" << endl;
        }
    private:
        int _ix;
        int _iy;
    };
private:
    Point _pt1;
    Point _pt2;
public:
    LinePimpl(int x1, int y1, int x2, int y2)
    : _pt1(x1, y1), _pt2(x2, y2)
    {
        cout << "LinePimpl::LinePimpl(int x1, int y1, int x2, int y2)" << endl;
    }
    ~LinePimpl()
    {
        cout << "LinePimpl::~LinePimpl()" << endl;
    }
    void printPimpl()
    {
        _pt1.printPoint();
        cout << "------>" << endl;
        _pt2.printPoint();
    }
};


Line::Line()
{
    cout << "Line::Line()" << endl;
}
Line::Line(int x1, int y1, int x2, int y2)
:_pimpl(new LinePimpl(x1,y1,x2,y2))
{
    cout << "Line::Line()" << endl;
}
Line::~Line()
{
    if(_pimpl)
        delete _pimpl;
    cout << "Line::~Line()" << endl;
}
void Line::printLine()
{
    _pimpl->printPimpl();
}

main.cc
#include "Line.h"

int main(int argc, char *argv[])
{
    Line line(1,2,3,4);
    line.printLine();
    return 0;
}

单例对象的自动回收

作用:避免对程序进行内存泄漏检查时造成不必要的麻烦

嵌套类+静态对象(多线程不安全)
#include <iostream>
using namespace std;

class Singleton
{
    class autoRelease
    {
    public:
        autoRelease() { cout << "autoRelease()" << endl; }
        ~autoRelease() { 
            cout << "~autoRelease()" << endl; 
            if(_pinstance)
                delete _pinstance;
        }
    };
public:
    static Singleton *getinstance()
    {
        if(_pinstance == nullptr)
            _pinstance = new Singleton();
        return _pinstance;
    }
private:
    Singleton() { cout << "Sinleton()" << endl; }
    ~Singleton() { cout << "~Singleton()" << endl; }
    static autoRelease _auto;
    static Singleton *_pinstance;
};
Singleton *Singleton::_pinstance = nullptr;
Singleton::autoRelease Singleton::_auto;
int main(int argc, char *argv[])
{
    Singleton *p1 = Singleton::getinstance();
    Singleton *p2 = Singleton::getinstance();
    cout << p1 << endl << p2 << endl;
    return 0;
}
静态成员函数+atexit()
#include <iostream>
using namespace std;
class Singleton
{
public:
    static Singleton* getinstance()
    {
        if(_pinstance == nullptr)
        {
            atexit(destory);
            _pinstance = new Singleton();
        }
            
        return _pinstance;
    }   
    static void destory()
    {
        if(_pinstance)
            delete _pinstance;
    }
private:
    Singleton(){ cout << "Singleton()" << endl; }
    ~Singleton(){ cout << "~Singleton()" << endl; };
    static Singleton *_pinstance;
};
Singleton * Singleton::_pinstance = nullptr;

int main(int argc, char *argv[])
{
    Singleton *p1 = Singleton::getinstance();
    Singleton *p2 = Singleton::getinstance();
    cout << p1 << endl << p2 << endl;
    return 0;
}
pthread_once() +atexit() (多线程安全,推荐使用)
#include <cstdlib>
#include <pthread.h>
#include <iostream>
using namespace std;
class Singleton
{
public:
    static Singleton *getinstance()
    {
        pthread_once(&_once, init);
        return _pinstance;
    }
    static void init()
    {
        atexit(destory);
        if(_pinstance == nullptr)
            _pinstance = new Singleton();
        
    }
    static void destory()
    {
        if(_pinstance)
            delete _pinstance;
    }
private:
    Singleton(){ cout << "Singleton()" << endl; }
    ~Singleton(){ cout << "~Singleton()" << endl; }
    static Singleton *_pinstance;
    static pthread_once_t _once;
};

Singleton *Singleton::_pinstance = nullptr;
pthread_once_t Singleton::_once = PTHREAD_ONCE_INIT;

int main(int argc, char *argv[])
{
    Singleton *p1 = Singleton::getinstance();
    Singleton *p2 = Singleton::getinstance();
    cout << p1 << endl << p2 << endl;
    return 0;
}

std::string的底层实现

Eager-Copy
COW

全称为Copy-On-Write,即写时复制:当对字符串进行复制或赋值时,并不马上真正进行赋值,只有当字符串的内容要进行修改时,才进行深拷贝
实现代码

#include <cstring>
#include <iostream>
using namespace std;

class CowString
{
    class CharProxy
    {
    public:
        CharProxy(CowString& self, int idx)
        :_self(self)
        ,_idx(idx)
        {
            cout << "CharProxy(CowString& self, int idx)" << endl;
        }
        ~CharProxy()
        {
            cout << "~CharProxy()" << endl;
        }
        operator char()
        {
            return _self._pstr[_idx];
        }
        char &operator=(const char &ch);
    private:
        CowString &_self;
        int _idx;
    };
public:
    CowString()
    :_pstr(new char[5]()+4)
    {
        *(_pstr-4) = '\0';
        initref();
        cout << "CowString()" << endl;
    }
    CowString(const char *pstr)
    :_pstr(new char[strlen(pstr)+5]()+4)
    {
        cout << "CowString(const char *pstr)" << endl;
        strcpy(_pstr, pstr);
        initref();
    }
    CowString(const CowString& rhs)
    :_pstr(rhs._pstr)
    {
        cout << "CowString(const CowString& rhs)" << endl;
        increaseref();
    }
    CowString& operator=(const CowString& rhs)
    {
        cout << "CowString& operator=(const CowString& rhs)" << endl;
        if(this != &rhs)
        {
            release();
            _pstr = rhs._pstr;
            increaseref();
        }
        return *this;
    }
    int length()
    {
        return *(int*)(_pstr-4);
    }
    const char *c_str()
    {
        return _pstr;
    }
    void showref()
    {
        cout << *(int*)(_pstr-4) << endl;
    }
    friend std::ostream &operator<<(std::ostream &os, const CowString &rhs);
    CharProxy operator[](int idx);
private:
    void initref()
    {
        *(int *)(_pstr-4) = 1;
    }
    void increaseref()
    {
        ++*(int *)(_pstr-4);
    }
    void decreaseref()
    {
        --*(int *)(_pstr-4);
    }
    void release()
    {
        decreaseref();
        if(*(int *)(_pstr-4) == 0)
            delete [](_pstr-4);
    }
    char *_pstr;
};

CowString::CharProxy CowString::operator[](int idx)
{
    return CharProxy(*this, idx);
}
std::ostream &operator<<(std::ostream &os, const CowString &rhs)
{
    cout << rhs._pstr;
    return os;
}
char &CowString::CharProxy::operator=(const char &ch)
{
    if(_idx >= 0 && _idx < _self.length())
    {
        if(*(int*)(_self._pstr-4) > 1)
        {
            _self.release();
            char *tmp = new char[strlen(_self._pstr)+5]()+4;
            strcpy(tmp, _self._pstr);
            _self._pstr = tmp;
            _self.initref();
        }
        _self._pstr[_idx] = ch;
        return _self._pstr[_idx];
    }
    else
    {
        static char nullchar = '\0';
        return nullchar;
    }
}

int main(int argc, char *argv[])
{
    CowString s1 = "hello,world";
	CowString s2 = s1;
	CowString s3 = "shenzhen";
	cout << "s3 = " << s3 << endl;

	s3 = s1;
	cout << "执行赋值操作之后:" << endl;
	cout << "s1 = " << s1 << endl;
	cout << "s2 = " << s2 << endl;
	cout << "s3 = " << s3 << endl;
	printf("s1's address is %p\n", s1.c_str());
	printf("s2's address is %p\n", s2.c_str());
	printf("s3's address is %p\n", s3.c_str());
	cout << "s1's refcount = " << endl;
    s1.showref();
	cout << "s2's refcount = "<< endl;
    s2.showref();
	cout << "s3's refcount = "<< endl;
    s3.showref();

	cout << "\n 修改共享字符串的内容之后:" << endl;
	s3[0] = 'X';
	cout << "s1 = " << s1 << endl;
	cout << "s2 = " << s2 << endl;
	cout << "s3 = " << s3 << endl;
	printf("s1's address is %p\n", s1.c_str());
	printf("s2's address is %p\n", s2.c_str());
	printf("s3's address is %p\n", s3.c_str());
	cout << "s1's refcount = " << endl;
    s1.showref();
	cout << "s2's refcount = "<< endl;
    s2.showref();
	cout << "s3's refcount = "<< endl;
    s3.showref();

	cout << "\n 执行读操作之后:" << endl;
	cout << "s1[0] = " << s1[0] << endl;
	cout << "s1 = " << s1 << endl;
	cout << "s2 = " << s2 << endl;
	cout << "s3 = " << s3 << endl;
	printf("s1's address is %p\n", s1.c_str());
	printf("s2's address is %p\n", s2.c_str());
	printf("s3's address is %p\n", s3.c_str());
	cout << "s1's refcount = " << endl;
    s1.showref();
	cout << "s2's refcount = "<< endl;
    s2.showref();
	cout << "s3's refcount = "<< endl;
    s3.showref();
    return 0;
}
SSO

全称为Short-String-Optimazation,即短字符串优化:当字符串长度<=15个字节时,字符串内容作为对象的一部分,否则,该字符串用堆空间进行存储

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值