C++基础学习-5

158 阅读2分钟

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而直接调用该函数,为一种报错机制。