备战2020校招日记----4.16

目标完成情况

  • 两道LeetCode ----- 没做,实在没心思做。。有点懒
  • 看侯捷视频,独立实现Complex类 ----- 基本完成,但是在侯捷的动态数组分配的地方听得有点蒙蔽,我感觉他可能讲错了。
  • csapp第7章看完前3节 -------- 前面比较短,看了5节。

知识复盘

1. C++语法实战

整个上午都在Linux下用vim尝试独立实现Complex这个类。主要是为了熟悉C++的操作符重载、const的使用等基本语法,同时也体会到了ide的方便性,因为在shell下每次都要重新编译,然后运行,还是挺麻烦的。遇到了很多bug,这部分我不默写了。

1.1 关于内联函数

主要将其视为宏定义的替代版即可,或者说升级版。所以,一个函数,他是不是内联函数,和他是成员函数还是全局函数是没有关系的。按照侯捷的说法,所有的函数都最好添加inline关键字,意思是建议编译器给她作为内联函数来编译,但这仅仅是建议。

1.2 二元操作符的全局形式的重载

需要传入两个参数,而不像成员函数的形式,只要传入一个,成员函数之所以只要传入一个参数,是因为,隐式地传入了一个this指针,指向了调用者自身。

1.3 关于隐式构造函数(non explicit)

隐式的调用构造函数,构造出来的是右值,右值是不能被non-const的引用绑定的,因此这个时候需要用const参数来接收。我开始时没有将参数设为const的,遇到了下面的错误:

error: invalid initialization of non-const reference of type ‘Complex&’ from an rvalue of type ‘Complex’

将接收参数改成const就好了。

1.4 关于操作符‘<<’的重载

这个操作符的重载一定要是全局形式的,因为否则的话使用起来会非常丑陋,不符合需求。
需要传入两个参数,第一个参数是ostream对象,一定要是non-const的,而第二个参数一定是const的,因为我们只是要将第二个参数输出,并不会改变他。如下:

ostream& operator << (ostream& os, const Complex& x){
        return os <<  x.real() << "+" << x.image() << "i";
}
1.5 关于赋值运算符‘=’的重载

由于Complex内部不带指针,因此这只是最基本的赋值运算符的重载。
我想说的是,这个运算符通常建议设置成成员函数的形式,这和<<相反。这样可以确保左边的值是对象,从而不会出现将一个对象赋值给常量的情形。如下:

Complex& operator = (const Complex& b){
         this->re = b.re;
         this->im = b.im;
         return *this;
}

还有一点,我认为是<<和=运算符重载的共同点,就是内部都是使用了C++语言自带的“原始”操作符。例如<<的重载,利用了ostream的<<, 而‘=’的重载,在内部实现的时候,也还是利用了语言自带的‘=’。

1.6 关于带指针的类的设计

这个部分主要是下午看了侯捷的视频,没有动手实现,主要讲了三大函数:拷贝构造函数,拷贝赋值运算符,析构函数。在带指针的类中,我们通常需要自己重新实现这三个函数,而不是使用编译器自动生成的。

然后讲了一些深拷贝浅拷贝的东西。

让我感觉收获最大的地方是,在重载拷贝赋值运算符的时候,检测是否为自我赋值是很有必要的,否则的话,一旦真的发生了自我赋值,就会出错,因为在我们的实现中,我们会首先将原先的数据删除,然后创建空间,然后拷贝,而如果是自己给自己赋值的话,那么在删除数据之后,就再也找不到原先的数据了,从而无从拷贝。这就很搞笑了。

inline
String& String::operator=(const String& str){
    if(this == &str){ // 检测自我赋值,不可少!!!!
        return *this;
    }
    // 删除原有数据和空间
    delete[] m_data; /// 虽然只有一个指针,但是一定要加[]
    // 创建新的合适大小的空间
    m_data = new char[strlen(str.m_data)+1];
    // 数据拷贝
    strcpy(m_data, str.m_data);
    return *this;
}
2.《深入理解计算机系统》第7章 链接

看了前5节。
稍微有点蒙蔽。
但是我还是认为这一章非常重要,在将来的实际工程中,会经常用到此处的知识。下面的内容属于强行默写。

链接概述

链接主要做两件事情:

  1. 符号解析
  2. 地址重定位

在链接之前已经经历了预处理器、编译器、汇编器的处理,得到了二进制可重定位目标文件。但是这些文件是不可执行的,为什么呢?两个原因:

  1. 目标文件中有很多占位符,需要填充地址。
  2. 多个目标文件中的符号的相对地址没有确定,我们要的是一个目标文件,而不是多个。

这两个问题都将由链接器来解决,也就是完成符号解析地址重定位。说得好像有点啰嗦。

符号解析概述

首先链接器看到的是目标代码(也称为目标文件),而目标代码是分节的,节是怎么分出来的呢?在这里插入图片描述
目标文件有一个起始的16字节来标识目标文件的开始。后面有个字段指出了一个节(节头部表),而这个节当中又存储了其他所有节的地址,从而就可以分出所有的节了。

有了节又怎样呢?节是用来分类存放信息的。
例如.text 节是用来存放编译后的代码的。而.symtab节是用来存放本目标文件中的所有符号信息的。而.data就是我们常说的静态区(数据区),他会存放已经初始化的全局变量和静态变量,例如程序中有一句static int x = 3,这个x不是放在栈中的,而是放在.data节中的,可见这个x在编译之后、连接之前就存在了。

后面详述了.symtab节,这个节就是存放符号表的节,也就是存放了所有的符号信息,每个符号有哪些信息?也就是说这个表有哪些字段?分别介绍了每个字段,暂时不太理解具体有什么用。下图是一个例子:
在这里插入图片描述明天再看吧。总之在搞清楚符号和符号表之后,应该就可以解析了,所谓解析,我暂时的理解就是将符号换成相应的地址。有点懵逼。

明天加油,今天效率还可以吧,毕竟动手了,我相信只要动手实操,就一定是很有进步的。当然还要结合书本,才能引导思考,否则就是机械操作了。孔子曾经说过:学而不练则惘,练而不学则原地转圈圈。而我想要的是螺旋上升哈哈。

明日目标

  1. 两道LeetCode
  2. 侯捷的基础视频快速过完,因为感觉视频看太多收获很小了,我缺的不是理论,而是实操。
  3. csapp第7章起码看完符号解析,地址重定位开个头。这部分比较难,感觉。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值