2020校招备战日记5.12 ---- C++的析构函数为什么要设成虚函数, 栈中存放什么, 未初始化的静态变量存在哪里,螺旋数组,string类的实现

0. 目标完成情况

  • unp第2章和第3章看完 ---------- 两天了还是没怎么看,这两天处于面试适应期,效率低下,有点懒,以后每天不管怎样都要更新博客日记。
  • 看看面经
  • LeetCode 一道题

1. 所学回顾

1.1 C++的析构函数为什么要设成虚函数

是为了在使用父类指针来调用析构函数的时候,调用的是动态类型对象的析构函数,而不是按照静态类型来调用。
如果按照静态类型来调用的话,那么就仅仅是调用父类的析构函数了,这会导致子类的析构函数没有被执行,从而导致内存泄露。而如果按照动态类型来调用,就是调用的实际子类的析构函数,从而可以先执行子类的析构函数,再执行父类的析构函数,避免了内存泄露。
这里还录制了一个小视频

1.2 栈中存放什么

栈分为用户栈内核栈

  1. 内核栈:当程序从用户模式进入内核模式的时候,会将返回地址、一些处理器状态压入内核栈。
  2. 用户栈:当过程调用的时候,会将返回地址、一些处理器状态压入用户栈,在函数执行的过程中,栈中会存放函数内的局部变量。

总结: 如果笼统地问栈中存放什么,应该答:局部变量、返回地址和一些处理器状态。 (今天面试只想起来局部变量,没想起来返回地址,很遗憾。)
在这里插入图片描述
实际上,如上图所示,在main函数之前,还会存放shell字符串,环境变量。

1.3 未初始化的静态变量存在哪里

在.bss段
初始化了的在.data段
代码段在.text段
在这里插入图片描述

1.4 螺旋数组

题目如下图:
在这里插入图片描述
我的代码如下,为简单起见,没有考虑越界问题。

#include<iostream>
#include<vector>
using namespace std;
int fun(vector<vector<int>>& nums, int x, int y){
	int x0=0, y0=0;
	// 找到1所在的位置
	for(int i=0; i<nums.size(); i++){
		for(int j=0; j<nums.size(); j++){
			if(nums[i][j] == 1){
				x0=i;
				y0=j;
				break;
			}
		}
	}
	int i=0, j=0; // i和j为相对的横纵坐标
	int step = 1;
	while(i!=x || j!=y){
		for(int up = 0; up<step; up++){
			i++;
			if(i == x && j == y) return nums[x0-j][y0+i];
		}
		for(int left = 0; left<step; left++){
			j--;
			if(i == x && j == y) return nums[x0-j][y0+i];
		}
		step++;
		for(int bot = 0; bot<step; bot++){
			i--;
			if(i == x && j == y) return nums[x0-j][y0+i];
		}
		for(int right = 0; right<step; right++){
			j++;
			if(i == x && j == y) return nums[x0-j][y0+i];
		}
		step++;
	}
}

int main(){
	vector<vector<int>> res = {
		{20, 7, 8, 9, 10},
		{19, 6, 1, 2, 11},
		{18, 5, 4, 3, 12},
		{17, 16,15,14,13},
	};
	cout << fun(res,-2, -1) << endl;
} 
1.5 string类的实现

主要实现了几个基本的构造和运算,拷贝都是深拷贝,暂时没有考虑copy on write问题。
代码如下,可以直接运行:

#include<iostream>
#include<cstring>
using namespace std;
class String{
	private:
		char* m_p;
	public:
		String(const char* str = nullptr);
		String(const String& str);
		~String();
		String& operator=(const String& str);
		String operator+(const String& str);
		bool operator==(const String& str);
		char operator[](int index);
		int getLength();
		char* getMp() const {
			return this->m_p;
		}
};

String::String(const char* str){
	if(str == nullptr){
		this->m_p = 0;;
	}else{
		this->m_p = new char[strlen(str) + 1];
		strcpy(this->m_p, str);
	}
}

String::String(const String& str){
	if(str.m_p == nullptr){
		this->m_p = nullptr;
	}else{
		this->m_p = new char[strlen(str.m_p) + 1];
		strcpy(this->m_p, str.m_p);
	}
} 

String::~String(){
	if(this->m_p){
		delete[] this->m_p;
		this->m_p = 0;
	}
}

String& String::operator=(const String& str){
	if(this->m_p != nullptr){
		delete[] this->m_p;
	}
	if(str.m_p == nullptr){
		this->m_p = 0;
	}else{
		this->m_p = new char[strlen(str.m_p) + 1];
		strcpy(this->m_p, str.m_p);
	}
}

String String::operator+(const String& str){
	String res;
	if(str.m_p == nullptr){
		res = *this;
	}else if(this->m_p == nullptr){
		res = str;
	}else{
		res.m_p = new char[strlen(this->m_p) + strlen(str.m_p) + 1];
		strcpy(res.m_p, this->m_p);
		strcat(res.m_p, str.m_p);
	}
	return res;
}

bool String::operator==(const String& str){
	if(this->m_p == nullptr && str.m_p == nullptr) return true;
	if(strlen(this->m_p) != strlen(str.m_p)) return false;
	if(strcmp(this->m_p, str.m_p) == 0) {
		return true;
	}else {
		return false;
	}
}

char String::operator[](int index){
	if(index < strlen(this->m_p) && index > 0){
		return this->m_p[index];
	}
}

int String::getLength(){
	return strlen(this->m_p);
}

ostream& operator << (ostream& os, const String& str){ // 全局函数 
	os << str.getMp(); 
	return os;
}
int main(){
	String str = String("hello");
	cout << str << "\t" << str.getLength() << endl;
	String str2 = String("  world!");
	cout << str2 <<"\t" << str2.getLength() << endl;
	cout << str + str2 << endl;
	cout << (str2 == str)<< endl;
	cout << str[3] << endl;
}

2. 明日(5月13日)目标

  1. 上午:复习智能指针的实现、vector的实现
  2. 下午:牛客2道题,leetcode每日一题。有时间看一节侯捷的stl视频。
  3. 晚上:unp第三章看完。
  4. 一定一定要写博客。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值