20200111

一.CPP

1.string三种历史实现

  1. 浅拷贝:只要赋值即new空间进行深拷贝
  2. 增加引用计数,不修改则计数加一,修改则深拷贝
  3. 当字符串的长度小于等于15个字节时,buffer直接存放整个字符串;当字符串大于 15个字节时,buffer存放的就是一个指针,指向堆空间的区域。这样做的好处是, 当字符串较小时,直接拷贝字符串,放在string内部(通常为栈),不用获取堆空间,开销小。
class string {

union Buffer{ char * _pointer; char _local[16]; };

Buffer _buffer; size_t _size; size_t _capacity;

};

2.最佳策略

以上三种方式,都不能解决所有可能遇到的字符串的情况,各有所长,又各有缺 陷。综合考虑所有情况之后,facebook开源的folly库中,实现了一个fbstring, 它根 据字符串的不同长度使用不同的拷贝策略, 最终每个fbstring对象占据的空间大小 都是24字节。

  1. 很短的(0~22)字符串用SSO,23字节表示字符串(包括’\0’),1字节表示长度

  2. 中等长度的(23~255)字符串用eager copy,8字节字符串指针,8字节size, 8字节capacity.

  3. 很长的(大于255)字符串用COW, 8字节指针(字符串和引用计数),8字节 size,8字节capacity.

该技术目前在多核处理器不能很好的实现,目前大部分系统采用sso方法
CPU的原子操作虽然比mutex锁好多了, 但是仍然会带来性能损失, 原因如下:

  1. 阻止了CPU的乱性执行.
  2. 两个CPU对同一个地址进行原子操作, 会导致cache失效, 从而重新从内存中读数据.
  3. 系统通常会lock住比目标地址更大的一片区域,影响逻辑上不相关的地址访问

作业:分离[]后的读写操作

class String{
public:
 	//内部友元类,区别派生类
    class CharProxy{
    public:
        CharProxy(String &str, int index);
        CharProxy& operator=(const CharProxy&rhs);//左值运用
        CharProxy& operator=(char c);
        operator char()const;//右值运用
    private:
        String &theString;
        int charIndex;
    };
    const CharProxy operator[](int index)const;
    CharProxy operator[](int index);
    friend class CharProxy;
private:
    RCPtr<StringValue>value;
};
//重载String类下标符,两版
const String::CharProxy    String ::operator[](int index)const {
    return CharProxy(const_cast<String&>(*this), index);
}

String::CharProxy String::operator[](int index){
    return CharProxy(*this, index);
}
//构造内部类类型
String::CharProxy::CharProxy(String &str, int index) :theString(str), charIndex(index){}
//重载内部类char转换操作
String::CharProxy::operator char()const{
    return theString.value->data[charIndex];
}
//重载内部类赋值
String::CharProxy&String::CharProxy::operator=(const CharProxy &ths){
    if (theString.value->isShared()){
        theString.value = new StringValue(theString.value->data);
    }
    theString.value->data[charIndex] = rhs.theString.value->data[ths.charIndex];
    return *this;
}

String::CharProxy&String::CharProxy::operator=(char c){
    if (theString.value->isShared()){
        theString.value = new StringValue(theString.value->data);
    }
    theString.value->data[charIndex] = c;
    return *this;
}

关于宏
https://blog.csdn.net/yuanxuegui2008/article/details/6385298
参数捕捉的方式导致宏不能解决这个问题

预习下周

1.多态
静态多态:函数运算符重载
动态多态:虚函数(默认)

基类中必须声明,派生类可不加virtual
派生类中重定义必须与基类中返回类型/参数个数/参数类型一致

2.继承

ML

8.3 模型提出

在这里插入图片描述

9.2反向传播推到自闭

发布了7 篇原创文章 · 获赞 0 · 访问量 94

猜你喜欢

转载自blog.csdn.net/weixin_44323639/article/details/103933174
今日推荐