type
status
slug
date
summary
tags
category
password
icon
前期准备
vitualBox的一些命令指南:查看当前虚拟机VBoxManage list vms查看当前正在运行的虚拟机VBoxManage list runningvms启动虚拟机VBoxManage startvm 虚拟机名无前端图形界面方式启动虚拟机VBoxManage startvm 虚拟机名 --type headless使用 VRDP 方式通过命令行启动虚拟机: (3389)VBoxManage startvm 虚拟机名 --type vrdp关闭虚拟机VBoxManage controlvm 虚拟机名 poweroffVBoxManage controlvm <uuid|vmname> acpipowerbutton 温和关闭(没有彻底断电stop)VBoxManage [-v|-version] 显示virtualbox的版本号VBoxManage -nologo 隐藏logoVBoxManage -convertSettings 允许自动转换设置文件VBoxManage -convertSettingsBackup 允许自动转换设置文件,并在转换前作备份VBoxManage -convertSettingsIgnore 允许自动转换设置文件,但是不保存结果
编程风格—modern c++
The basic idea is to make sure that every object is designed to have the smallest possible
public interface, has a lot of internal safety checks and is hard to use improperly, and knows
how to clean up after itself.
operations happen in the constructor to an object, and the opposite operation happens in the destructor. This style is called “Resource acquisition is initialization,” or RAII.
- Use the language documentation at https://en.cppreference.com as a resource. (We’d recommend you avoid cplusplus.com which is more likely to be out-of-date.)
- Never use malloc() or free().
- Never use new or delete.
- Essentially never use raw pointers (*), and use “smart” pointers (unique ptr or shared ptr) only when necessary. (You will not need to use these in CS144.)
- Avoid templates, threads, locks, and virtual functions. (You will not need to use these in CS144.)
- Avoid C-style strings (char *str) or string functions (strlen(), strcpy()). These are pretty error-prone. Use a std::string instead.
- Never use C-style casts (e.g., (FILE *)x). Use a C++ static cast if you have to (you generally will not need this in CS144).
- Prefer passing function arguments by const reference (e.g.: const Address& address)
- Make every variable const unless it needs to be mutated.
- Make every method const unless it needs to mutate the object.
- Avoid global variables, and give every variable the smallest scope possible.
Before handing in an assignment, run
cmake --build build --target tidy
for
suggestions on how to improve the code related to C++ programming practices, and
cmake --build build --target format
to format the code consistentlystart task1
Please read over the public interfaces (the part that comes after “public:” in the files
util/socket.hh and util/file_descriptor.hh. (Please note that a Socket is a type of
FileDescriptor, and a TCPSocket is a type of Socket.)
从socket.hh开始解析:
socket本质上也就是一个文件,所以构造这个类的时候就是让socket继承的FileDescriptor这个类(这个类后面会仔细分析)
我们重点是在public interface
这样看太麻烦了,主要还是结合https://cs144.github.io/doc/lab0/index.html看
Address() [2/4]
Address::Address(const std::string & hostname,const std::string & service )
Construct by resolving a hostname and servicename.
Parameters[in]hostnameto resolve[in]servicename (from
/etc/services
, e.g., "http" is port 80)下面左图是我代码write的内容对比右图telnet下输入http后得到的相应,因为代码返回的是400,很怪。结果最后居然是字符串里面 HTTP/1.1这个字符串后面跟了一个空格导致的。
核心代码和注释如下:(去掉注释恰好10行)
continue task2
you will implement, in memory on a single computer, an object
that provides this abstraction—the abstraction of a reliable byte stream.
Bytes are written on the “input” side and can be read, in the same sequence, from the “output”
side. The byte stream is finite: the writer can end the input, and then no more bytes can be
written. When the reader has read to the end of the stream, it will reach “EOF” (end of file)
and no more bytes can be read.
Your byte stream will also be flow-controlled to limit its memory consumption at any given
time. The object is initialized with a particular “capacity”: the maximum number of bytes
it’s willing to store in its own memory at any given point. The byte stream will limit the
writer in how much it can write at any given moment, to make sure that the stream doesn’t
exceed its storage capacity. As the reader reads bytes and drains them from the stream, the
writer is allowed to write more. Your byte stream is for use in a single thread—you don’t
have to worry about concurrent writers/readers, locking, or race conditions.
To be clear: the byte stream is finite, but it can be almost arbitrarily long 4 before the writer
ends the input and finishes the stream. Your implementation must be able to handle streams
that are much longer than the capacity. The capacity limits the number of bytes that are
held in memory (written but not yet read) at a given point, but does not limit the length
of the stream. An object with a capacity of only one byte could still carry a stream that is
terabytes and terabytes long, as long as the writer keeps writing one byte at a time and the
reader reads each byte before the writer is allowed to write the next byte.
clangd LSP报的unused 错很烦,这里我们写一个.clangd 把它去掉:
编译的cmake命令:
cmake --build build --target check0
这部分有两个点需要注意:
- code里面的三个class,有一个downcast的强制转换,并且我发现,这个题应该是利用了一个UB行为,因为把bytestream类的实例直接转换为reader和writer(它转换函数里面有保证,让reader和writer里面不会增加成员变量)
- 优化环节需要仔细的考虑string这个东西只被初始化一次,不要复制,通过使用string_view来完成一些指针的操作。还有使用mov这种迁移数据。还有,接收字符串的时候也应该使用deque这样的数据类型,不要对字符串进行拼接,拼接是两个字符串产生产生一个新的(老的要复制),而移动入deque是将新的字符串移动进老的队列,老的不会复制。
尊重原作者,就不贴代码了,附上一个优化参考:
c++语法部分积累
1(void)data
在C++中,(void)data;
是一种常见的编程技巧,用于消除未使用变量的警告。编译器通常会发出警告,当你声明了一个变量但没有使用它时。这是因为未使用的变量可能是由于编程错误(例如,拼写错误或者遗漏的代码)导致的,编译器发出警告是为了帮助你发现这种可能的错误。然而,有时候你可能故意声明一个变量但不使用它。例如,你可能需要一个函数符合特定的签名,但不需要使用所有的参数。在这种情况下,你可以使用(void)data;
来消除编译器的警告。这行代码的意思是“我知道data
没有被使用,这是故意的,不要发出警告”。注意,(void)data;
并不会对data
做任何操作,也不会改变它的值。它只是一种告诉编译器“我知道我没有使用这个变量”的方式。
- 作者:liamY
- 链接:https://liamy.clovy.top/article/cs144/lab0
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。