【C++学习】谈谈我对C++代码重构的认识

C++系列文章

【C++学习】谈谈我对C++中delete的看法



前言

本文基于我对重构的理解,以及在网上search的关于重构的各种相关知识来做一个归纳。

C++的代码重构,首先要对C++的数据结构,代码结构,封装继承虚函数等的使用要有基础,其次要对已有代码有充分的了解和认知,最后是掌握一定的重构技巧和方法。

重构时需要有一定的步骤,其中最重要也是最难的一部分是对类的重构,我理解的类的重构步骤是这样的,首先对类的功能和公开方法(外部可调用的方法)进行设计,再考虑类具体实现一些什么功能,编写私有成员和保护成员。


一、C++相关基础

1. 类和对象

类成员函数能干什么?

  • 能操作类的任意对象,访问对象中的所有成员。类的成员函数与类中定义的变量都是类的成员。
  • 在类中定义的成员函数自动把函数声明为内联的

protected一般是用来在基类中定义受保护的成员函数或变量,来让派生类进行访问。

无论采用何种继承方式:

  • private 成员只能被本类成员(类内)和友元访问,不能被派生类访问;
  • protected 成员可以被派生类访问。

this指针和类的指针:

  • this指针是什么,指向哪里?

    • 它是所有成员函数的隐含参数
    • 在成员函数内部它可以用来指向调用该成员函数的对象
  • 为什么要定义指向类的指针?

    • 定义一个指向类的指针可以用来赋值为类的对象的地址
    • 可以用指针来操作该对象可以使用的成员函数。
class Box{
    
    
public:
    Box(int _width = 10){
    
    width = _width;}
    int getValue(){
    
    return width;}
private:
    int width;
};
Box Box1(4);
Box *ptrbox = nullptr; 
ptrbox = &Box1;
cout << ptrbox->getValue() << endl;

2. 继承

为什么要继承?

  • 使得创建和维护一个程序更加容易;
  • 重用代码功能和提高执行效率

继承是什么?

  • 继承就相当于自行车和公路车,折叠自行车的关系,根据修饰符来定义子类可以使用的变量和方法,子类也可以根据自身需要来定义新的方法和变量

note:

  • 如果编写的是一个基类,那么提供给子类可以使用的方法和变量都应该使用protected来修饰。

3. 函数重载

函数重载是什么?

  • 在同一作用域中,重复声明一个函数,与原函数具有相同的名称,但是参数列表和定义不相同

4. 多态

多态是什么?

  • 多态和父类子类继承的关系息息相关,多态意味着在调用一个对象的成员函数时,会根据对象的类型执行不同的函数

5. 虚函数

  • 在基类中声明为虚函数的函数,可以在子类中重新定义。可以写作纯虚函数

  • 纯虚函数不用给出函数的实现,而交给子类自己实现。

    virtual int area() = 0;
    

6. 抽象类

只要类中有一个成员函数声明为纯虚函数,则该类就称为抽象类。设计抽象类(通常称为 ABC)的目的,是为了给其他类提供一个可以继承的适当的基类。抽象类不能被用于实例化对象,它只能作为接口使用。如果试图实例化一个抽象类的对象,会导致编译错误。同时需要注意一点,如果声明为虚函数则需要在子类中都定义该虚函数,要有具体的实现。


二、重构的技巧与方法

为什么要重构

  1. 目的:是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。

  2. 随着时间的发展、需求的变化,必须不断的修改原有的功能、追加新的功能,还免不了有一些缺陷需要修改。为了实现变更,不可避免的要违反最初的设计构架。经过一段时间以后,软件的架构就千疮百孔了。bug越来越多,越来越难维护,新的需求越来越难实现,软件的构架对新的需求渐渐的失去支持能力,而是成为一种制约。

  3. 使用重构的方式,不改变系统的外部功能,只对内部的结构进行重新的整理。通过重构,不断的调整系统的结构,使系统对于需求的变更始终具有较强的适应能力

  4. 当你发现修改一个小功能,或增加一个小功能时,就引发一次代码地震,也许是你的设计抽象度不够理想,功能代码太过分散所引起的

1. 单元测试

  1. 用 Microsoft 适用于 C++ 的单元测试框架编写 C/C++ 单元测试 | Microsoft Docs

  2. 用测试资源管理器对现有的 C++ 应用程序进行单元测试 | Microsoft Docs

  3. 使用 Microsoft.VisualStudio.TestTools.CppUnitTestFramework | Microsoft Docs

2. 函数的重构

​ 可以分为几个部分来进行,主要是参考该博客中的代码重构(一):函数重构规则 - 青玉伏案 - 博客园 (cnblogs.com)

  1. Extract Method(提取函数) 将大函数按模块拆分成几个小的函数,但是不要过度封装
  2. Inline Method(内联函数) 与上面的提取函数是相对的
  3. Replace Temp with Query----以查询取代临时变量: 将一些临时变量使用函数替代
  4. Inline Temp —内联临时变量:与上面的Replace Temp with Query相反
  5. introduce Explaining variable 引入解释性变量 将复杂的表达式拆分成多个变量
  6. Split Temporary Variable-----分解临时变量:一心不可二用
  7. Remove Assignments to Parameters----移除对参数的赋值
  8. Replace Method with Method Object----以函数对象取代函数

3. 类的重构

​ 通常涉及到很多其他的类,这一部分的工作是最困难的

可参考:代码重构(二):类重构规则 - 青玉伏案 - 博客园 (cnblogs.com)

4. 数据的重构


三、可能的实施:

  1. 书写单元测试

  2. 整理代码 删除不需要的代码和函数

  3. 进行函数的重构,添加更多的注释

  4. 进行类和数据的重构

    notion:

    1. 平滑安全可停可续

总结

​重构还是很难的,可能刚开始觉得没啥,但是在实际的操作中可能会遇到很多的问题,api怎么编写,公开方法有哪些,有哪些类可以定义成基类,有可能会把之前的很多东西推翻。所以为什么有本书专门来讲重构呢?哈哈哈。我觉得先做好准备工作很重要,理清思路也很重要,尤其是在一个比较复杂的项目中,要杀出一条血路来,也不是那么容易的事。道阻且长,慢慢来吧。

以上就是今天的全部分享内容,欢迎大家指正,讨论!

猜你喜欢

转载自blog.csdn.net/Daibvly/article/details/119954750