书中没有讲到的知识
fstream默认不会创建文件
使用fstream的open函数打开文件时,若文件不存在,并不一定会创建文件。
// open函数的声明。
void open(const char* _Filename, ios_base::openmode _Mode = ios_base::in | ios_base::out,
int _Prot = ios_base::_Default_open_prot)
open(_Filename)
的打开模式默认为in | out
,此时虽然含有out
,但并不会创建文件。
若要自动创建不存在的文件,则不能含有in
模式,改为open(_Filename, out)
即可。
若不能判断文件是否存在,可以先用out
打开一下,然后再用in | out
来打开。
关于struct和class的区别
struct和class很相似。虽然class完全涵盖struct的功能,但依旧设立了struct关键字。
因为c++为了兼容c,而struct正是c的关键字,所以c++也增加了对struct的支持,同时还扩展了struct的功能。
在c++代码中,不推荐struct,因为有些功能和struct息息相关,却不能用struct实现,必须要class。比如赋值运算符重载。
模板函数的参数不能自动类型转换
在传递参数时,若行嘞不相同,则会自动转换,比如char传给int时,就会自动转换。
可是,在模板函数中,就要使类型一致,因为其不会自动转换:
// 报错:没有与参数列表匹配的 函数模板 "test" 实例。
template<typename T>
int test(T a, T b)
{
return a + b;
}
int main()
{
char a = 1;
int b = 2;
int c = test(a, b);
}
// 报错:“test”: 未找到匹配的重载函数。
// “void test(T,T)”: 模板 参数“T”不明确。可能是“int”或“char”。
// "void test(T,T)": 无法从 "int" 推导出 "T" 的 模板 参数。
template<typename T>
void test(T a, T b)
{
return;
}
int main()
{
char a = 1;
int b = 2;
test(a, b);
}
赋值运算符重载
书中提到,赋值运算符的重载函数必须是成员函数。
赋值运算符重载函数的使用方式可以等效成:
等于号左侧的变量.赋值运算符重载函数(等于号右侧的变量)
。
并且返回值要这样写:return *this;
。
有些运算符重载函数作为成员函数时,会对函数使用const修饰符,但是赋值运算符的重载函数不能用,因为要修改返回值,但参数可以使用const。
示例:
const LEN = 10;
class num
{
public:
char* n = nullptr;
num& operator=(const num& a)
{
delete n;
n = nullptr;
if (a.n != nullptr)
{
n = new char[LEN];
RtlCopyMemory(n, a.n, LEN);
}
return *this;
}
};
int main()
{
num a, b;
b.n = new char[LEN];
b.n[0] = 'a';
a = b;
std::cout << a.n[0];
}
下载地址
链接:PDF版本(253.53MB;源码201KB)
提取码:oz3y