Warning: 自家学习专用__by Arthur
1. struct 和 class
在实践中练习了struct 和 class:仅作为数据结构来存储数据的话,建议使用结构体,如果含有对数据的操作方法,使用class对象;
区别
struct结构体用来“包装”数据,不含对数据的操作方法(成员初始化函数除外); class类对数据的进行封装,暴露接口(对数据的操作方法或称函数);
初始化方式
- struct常用的有两种方式,直接初始化,或者定义结构体的初始化函数(不建议,违背了结构体和类的初衷);
- class 在定义成员变量是直接初始化(早先版本的VS可能报错),或者在类的构造函数中进行初始化(关于析构函数,如果类中没有指针成员变量,那就无须定义析构函数);
2. 接口
貌似在class中认为:接口 == 方法 == 函数也没啥问题,但是当听到专业名词“不要对外暴露出过多的接口时”就懵逼了(I'm a little white)。之所以遇到这个问题,是因为在定义类方法时,谨遵“函数功能尽可能单一,不能过度耦合”的教导,因此将本能够一个函数实现的功能拆分成了两个函数func-1和func-2,func-2仅仅是为了而被func-1调用,但是如此一来均暴露在*.h文件中,这就产生了暴露太多接口的问题。
解决方法:
- 将两个函数合并成一个函数(这是否算违背了教导?);
- 将函数func-2改写成static函数(注意区别静态成员函数,不同的概念, 文章讲述的很清楚,并放在*.cpp实现文件中,仅限该文件中访问。
3. 返回引用的函数
当返回引用时,若需传入参数,那么该参数也必须为引用,并且在函数体内不能返回局部变量的引用(返回指针的函数也一样),因为该函数结束后会释放内存,导致错误。参见不同函数返回类型文章
std::string& GetStr(){
static std::string str; //定义为静态变量,在该文件范围中非局部变量
return str;
}
void fun1(const std::string& strIns){
GetStr() = strIns; //函数作为位于等号左边,略显神奇
//首先运行GetStr()函数,返回值为静态变量-str,再进行赋值,实际上只是对str操作,好处是仅暴露接口;
背景:GetStr原本定义在*.h文件中,也是为了少暴露接口,将函数挪到*.cpp中,并进行了如上的改动;
}
纯虚函数
virtual void fuc()const { assert(0); } 函数体中 assert(0);的含义,因为就语句本身来说,永远都是false,作用是为了在避免在子类中不进行 override而直接调用该函数,为一种报错机制。