个人笔记
按照项目下的文档步骤:
// 1. 新建一个仓库 bustub-private
// 2. clone cmu db 远程代码到本地
git clone --bare https://github.com/cmu-db/bustub.git bustub-public
cd bustub-public
// 3. mirror到自己刚创建的远程仓库
git push --mirror git@github.com:sunshinejiali/bustub-private.git
// 4. 删除 cmu db 的本地副本
cd ..
rm -rf bustub-public
// 5. 拉取自己的远程仓库代码
git clone git@github.com:sunshinejiali/bustub-private.git
// 6. 添加 cmu-db 作为自己的第二远程仓库
cd bustub-private
git remote add public https://github.com/cmu-db/bustub.git
// 7. 验证是否已经添加
git remote -v
// result:
// origin [email protected]:sunshinejiali/bustub-private.git (fetch)
// origin [email protected]:sunshinejiali/bustub-private.git (push)
// public https://github.com/cmu-db/bustub.git (fetch)
// public https://github.com/cmu-db/bustub.git (push)
// 8. 提取 cmu-db 中的更改
git pull public master
使用 2020
年的版本,因此需要回退到之前提交的某一版本。
// 将代码回退到某一版本,head 指向当前的目标版本,删除之后的所有版本
git reset --hard 444765a
// 检查一下是否回退到正确的版本
git log
// (强制)提交更改
git push -f
报错
如果安装工具的时候报这个错误 ,这可能是因为在 windows 下编写好 .sh 文件后,在Linux 下运行报错。
// 报错
build_support/packages.sh: line 2: $'\r': command not found
build_support/packages.sh: line 13: $'\r': command not found
build_support/packages.sh: line 14: syntax error near unexpected token `$'{\r''
'uild_support/packages.sh: line 14: `main() {
//解决
// 使用 vim 打开文件
vim packages.sh
// 转换格式
:set ff=unix
// 保存文件
:wq
make format
报错
// make format 报错
/usr/bin/env: ‘python’: No such file or directory
make[3]: *** [CMakeFiles/format.dir/build.make:57: CMakeFiles/format] Error 127
make[2]: *** [CMakeFiles/Makefile2:287: CMakeFiles/format.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:294: CMakeFiles/format.dir/rule] Error 2
make: *** [Makefile:214: format] Error 2
// 解决:没有python, 安装
sudo apt-get install python
编译
mkdir build
cd build
cmake ..
make
// 测试
cd ..
cd build
make check-tests
for 循环
// 使用引用,允许修改数组中的元素。
for(int& i: someDataStructure) { doSomething();}
// 显示数组中的值,并保护数组成员,启用按值访问,不允许修改元素。
for(int i: someDataStructure) doSomething();
Lambda 函数的 Lamba 表达式——有主体但没有名字的函数
// firstPart 用于将在 lambda 函数内部利用的变量范围。
[firstPart](secondPart) TypeYouReturn{ BodyOfLambda}(acctualParameters);
// 例子1
double dUpperPart = [](double dX, double dY)double{ return dX*dX +dY*dY;}
// 例子2
vectror<int> iVector;
for_each( begin(iVector), end(iVector), [](int n){if(n%2==0)cout<<n<<end;});
Static Assertion
// 两部分:(1)需要判断的表达式。(2)不匹配显示的消息。
static_assert(evaluatedExpression, stringMessage);
// 例子
static_assert(sizeof(long long int)>=16;”This is unexpected”);
Move and &&
// 在类中实现移动构造函数
MovableClass(MovableClass&&);
// 需要移动配置的时候,这样调用
MovableClass&& operator=(MovableClass&&);
指针
unique_ptr 是 C++ 的新特性,它将使您能够保护存储在内存中的某些资源的所有权。如果某物拥有所有权,它就不能共享,但它是可移动的。这意味着您可以将其转移到另一个唯一的指针。unique_ptr 的示例将解决异常不安全代码。
unique_ptr<someType> suniquePtr(new someType(args));
...
uniquePtr.release();
shared_ptr 顾名思义,它适用于需要共享内存中某些资源的所有权的情况。
shared_ptr<someType> somePtr(new someType(args));
weak_ptr 允许访问可能存在于内存中的内容,如果您有占用内存的对象,则授予访问权限,并且可以删除该对象,如果上次使用过,则调用必要的析构函数。
weak_ptr<someType> weakPtr = somePtr;
统一初始化和初始化列表
如果希望使用构造函数,最好用 {} 替换旧样式的初始化 ()。
初始化
// 原来的
CSomeClass SomeObject(argument1,argument2);
// 新版的
CSomeClass SomeObject={argument1,argument2};
添加元素
// 原来的,已经过时了
vector <int> ourVector;
for(int i=0; i<5; ourVector.push_back(i++));
// 新版的
vector< int> ourVector={0,1,2,3,4,};
构造函数和继承
nSomeValue
class CSomeClass
{
private:
int nSomeValue=0;
...
}
class CChild: public CParent
{
public:
using CParent::CParent
}
虚函数
virtual
就足够了,每次在低级类中有方法时,都会用虚方法进行挖掘。final
,然后就无法修改方法的行为方式。多线程
编程风格
auto tuple = make_tuple(“triangle”, ‘t’, 10, 15, 20);
// 将具有一个元素字符串而另一个是向量的映射
map<string,vector<int>> aMap;
如果想要调试 main
函数。
gdb main
// or gdb a.out
// 运行
run
// or start
// 回溯,看是哪里的问题
backtrace
// 查看某个地址处的值, x 可以看作是 examine 的缩写。
x 0xffbef014
backtrace
条件和断点
item_to_remove
等于 1 时,在第 52 行中断。// 打断点,在第 52 行。
break LinkedList<int>::remove
// 仅在 item_to_remove 等于 1 时,在第 52 行中断。
condition 1 item_to_remove==1
quit
退出。
输入 step
可以继续运行,输入 next
将会一步一步向下进行。
ctrl + a
可以展示出一个文档。ctrl + L
可以从输出的显示中恢复到没有输出的显示,恢复正常的显示。q
退出。
在这个 Project
中,将实现三大类:Matrix
,RowMatrix
,和 RowMatrixOperations
。这些矩阵是简单的二维矩阵,必须支持加法、矩阵乘法和简化的 通用矩阵乘法(GEMM) 运算。
只需要修改一个文件:p0_starter.h
可以在BusTub 存储库中的 src/include/primer/p0_starter.h
中找到该文件。
在这个头文件中,定义了需要实现的三个类。该 Matrix
抽象类定义了派生类 RowMatrix
常用的功能。该 RowMatrixOperations
课程将使用 RowMatrix
对象来实现概述中所提到的操作。函数和成员变量在文件中指定。项目要求填写所有构造函数、析构函数和成员函数的实现。不要增加任何附加功能的原型或者成员变量。只需要修改我们已提供定义的功能。
由于有些代码未实现,所以测试文件中有 DISABLED 前缀的参数,用来禁止使用某些测试。所以,当我们实现了应该实现的功能后,可以删除 DISABLED 前缀,用来测试当前函数的功能。
// For example
// Original
TEST(StarterTest, **DISABLED_**MultiplyMatricesTest) {
// ....
}
// New
TEST(StarterTest, MultiplyMatricesTest) {
// ....
}
本地测试
// 如果之前建过 build,则直接到 build 下
make starter_test
./test/starter_test
提交测试之前,检查格式问题
// 在 build 下
make format
make check-lint
make check-clang-tidy
打包提交测试
zip project0.zip src/include/primer/p0_starter.h
C++动态分配内存数组 https://blog.csdn.net/DumpDoctorWang/article/details/80902947
C++ unique_ptr 智能指针
new
来分配内存,又因为 unique_ptr
不可拷贝和赋值,初始化必须使用直接初始化的方式。unique_ptr<int> number(new int()); //直接初始化
// 空的 ptr,使用 delete 释放。
unique_ptr<int> number;
// 空的 ptr,使用 d 删除器释放。
unique_ptr<int,D> number(d);
// 释放其指向对象
number = nullptr
// 放弃所指对象的控制权,并返回保存的指针,将 number 置为空,不会释放内存
number.release()
// 参数可以为空、内置指针,先将 number 所指对象释放,然后重置 number 的值.
number.reset(…)
它不能复制到另一个 ,按值传递给函数,也不能在需要创建副本的任何 C++ 标准库算法 unique_ptr
中使用。 在某一时刻,只能有一个unique_ptr
指向特定的对象。当unique_ptr
被销毁时,它所指向的对象也会被销毁。因此不允许多个unique_ptr
指向同一个对象。
只能 move
unique_ptr
。 这意味着,内存资源所有权将转移到另一个 unique_ptr
,并且原始 unique_ptr
不再拥有此资源。move
是在
中定义的。
unique_ptr
在
C++ 标准库的标头中定义。 它的效率与原始指针完全相同,可用于 C++ 标准库容器。 向 C++ 标准库容器添加 实例非常高效,因为 的移动构造函数无需 unique_ptr
unique_ptr
复制操作。
不能拷贝 unique_ptr
的规则有一个例外:我们可以拷贝或赋值一个将要被销毁的unique_ptr (C++ Primer 5th p418),可以从函数中返回一个unique_ptr。
std::unique_ptr<RowMatrix<T>> matrix(new RowMatrix<T>(matA->GetRows(), matB->GetColumns()));
// 因此这里这样写是没有问题的。
matrix = MultiplyMatrices(std::move(matA), std::move(matB));
if (matrix != nullptr) {
return AddMatrices(std::move(matrix), std::move(matC));
}
传 unique_ptr
参数可以使用引用避免所有权的转移,或者暂时的移交所有权。
用unique_ptr管理非new对象、没有析构函数的类时,需要向unique_ptr传递一个删除器。不同的是,unique_ptr
管理删除器的方式,必须在尖括号中unique_ptr
指向类型后面提供删除器的类型,在创建或 reset
一个这种 unique_ptr
对象时,必须提供一个相同类型的可调用对象(删除器),这个删除器接受一个 T*
参数。
在调用 number.release()
时不会释放 number
所指的内存的,这时返回值就是对这块内存的唯一索引,如果没有使用返回值释放内存或保存,这块内存就泄漏。
初始化:
new
初始化 linear
,data_
。memset
将新创建的数组清零。matrix
的 unique_ptr
。std::unique_ptr<RowMatrix<T>> matrix(new RowMatrix<T>(row, col);
unique_ptr
的移动:
MultiplyMatrices(std::move(matA), std::move(matB));
结果: