6,530
社区成员
发帖
与我相关
我的任务
分享代码重构是重构现有代码的过程,而其外部功能保持不变。通过重构,您可以简化复杂的代码结构,减少代码冗余,并增强代码的可重用性。Visual Studio提供了许多工具来帮助重构C++代码。本文将以bullet3开源代码为例,深入研究这些工具。
当更改出现在代码中多个位置的符号名称时,重命名工具非常有用。如果忽略了函数或变量的一个或多个实例,手动重命名可能会导致错误。但是,重命名工具可确保准确无缝地重命名所有实例。
请考虑“InProcessExampleBrowser.cpp”文件中的ExampleEntryPhysicsServer结构。假设我们想将m_menuLevel变量重命名为m_menuHierarchyLevel,以使其更具描述性。Visual Studio的“重命名”重构工具可以通过右键单击变量名,选择“重命名”,然后键入新名称来实现这一点。Visual Studio将自动将m_menuLevel的所有实例更新为m_menuHierarchyLevel,从而无需手动重命名。

GitHub Copilot的人工智能重命名建议是Visual Studio 2022中的一项新功能,它可以为任何C++标识符生成动态名称建议,有助于实现描述性和简洁性之间的平衡。这使您能够集中精力评估建议的名称,而不是生成新名称。
您可以通过选择“启用重命名建议”工具>选项>GitHub>Copilot聊天>预览功能来显示此功能。
让我们使用AI支持的重命名建议将m_name重命名为更具描述性的名称。首先,右键单击变量并选择“重命名”。在出现的“重命名”窗口中,单击新的闪耀图标以生成名称建议。Copilot聊天将根据标识符的使用方式和代码中的命名规则提供建议。让我们选择m_entryName,然后预览并应用更改。

更改签名功能可帮助您以安全高效的方式修改函数的参数。当我们想为ExampleEntryPhysicsServer构造函数的第一个实例的描述提供一个新参数时,我们将右键单击其名称,然后选择“快速操作和重构…”选项或使用Ctrl+。键盘快捷键。选择“更改签名”选项以打开一个新窗口。在这里,您可以添加、删除或重新排序参数。我们将通过键入类型和名称来添加一个常量字符串指针m_description。Visual Studio将相应地自动更新所有函数调用。
与重命名类似,逐个更改函数可能会导致错误,此工具可以自动执行此操作以消除这些错误。
提取函数是将复杂函数分解为更小、更易于管理的部分的好方法,并且如果程序中其他地方需要类似的功能,则可以潜在地重用代码块。在这段代码中,让我们从ExampleBrowserThreadFunc函数中提取代码块,该函数计算并更新deltaTimeInSeconds,然后根据deltaTimeInSeconds决定是更新图形还是重置时钟。此代码块是执行特定任务的逻辑单元,因此将其提取到单独的函数中是有意义的。
为此,请选择要提取的代码块,然后右键单击编辑器,然后选择“快速操作和重构…”选项。这将显示提取功能工具。选择该选项将打开一个新窗口,允许您选择新的函数名称和位置。一个新的功能将在选定的位置设置,头文件中有一个匹配的原型。将修改初始代码以调用此功能。
这有助于避免代码重复,并使代码更易于阅读和维护。
当处理具有纯虚拟函数的基类时,VisualStudio可以帮助在所有派生类中实现这些函数。在这个源代码中,实现了基类的所有纯虚拟函数。然而,为了举例,我修改了CommonRigidBodyBase结构,使其包含一个纯虚拟函数virtual void somePureVirtualFunction()=0;。现在,我们将使用Implement Pure Virtuals为BasicExample类中的somePureVirtualFunction()提供实现。
首先,右键单击派生类,然后从上下文菜单中选择“快速操作和重构…”选项,或者使用Ctrl+。键盘快捷键。然后选择Implement all Pure Virtuals for class BasicExample选项,纯虚拟方法将自动添加。

这节省了更多的时间,尤其是当你有很多虚拟函数时,因为这个工具将自动实现所有纯虚拟函数,而不是一个接一个地执行。
此功能使您能够轻松生成函数的声明或定义。让我们考虑添加一个新函数printExampleDetails,该函数获取指向ExampleEntriesPhysicsServer对象的指针,并打印服务器中注册的所有示例的详细信息。我们可以使用创建声明/定义工具来无缝地声明它。
选择代码块,然后右键单击编辑器,然后从上下文菜单中选择“快速操作和重构…”选项或使用Ctrl+。键盘快捷键。这将显示创建声明/定义选项,该选项将自动为该函数创建声明。

现在我们已经了解了如何声明函数,我们可以将函数的定义移动到相应的头文件中。在“ExampleEntries.cpp”文件中,我们有一个ExampleEntries All::registerExampleEntry函数。为了代码的可重用性,让我们将此函数的定义移到一个头文件中。
要移动函数位置,右键单击函数,然后从上下文菜单中选择“快速操作和重构…”选项或使用Ctrl+。键盘快捷键。然后选择“移动定义位置”选项,将函数移动到相应的头文件。

当您想通过将函数定义移动到适当的头文件来组织代码而不必手动执行时,此功能非常有用。
接下来,让我们来看一个具有特殊字符或转义序列的字符串。例如,如果您有一个字符串Torus(形状匹配),并且您想在Torus周围添加引号,则通常需要使用转义符,如:\“Torus\”(形状匹配(Shape Match))。然而,这会使字符串更难读取,尤其是在有许多特殊字符的情况下。为了解决这个问题,我们可以将它们转换为原始字符串文字,方法是在字符串前面加上R,并将其括在括号中,如下所示:R“(”Torus“(形状匹配))”。这告诉程序将括号中的所有字符解释为文字字符,而不是特殊字符。
若要转换为原始字符串文字,请右键单击字符串,然后从上下文菜单中选择“快速操作和重构…”选项或使用Ctrl+。键盘快捷键。然后,选择“转换为原始字符串文字”选项将完成该过程。Visual Studio将保留字符串的确切内容。

宏的读取和调试可能很困难,但将它们转换为constexpr函数可以增强代码的可读性和可维护性。此功能识别可以转换为constexpr的宏,然后提供一种将它们转换为现代C++constexpr表达式的快速方法。
要将#define ARRAY_SIZE_Y 5转换为constexpr,可以将鼠标悬停在宏下方的建议指示器(…)上,或者选择宏,然后从上下文菜单中选择“快速操作和重构…”选项(Ctrl+.键盘快捷键)。这将显示“将宏转换为Constexpr”选项,该选项将完成到Constexpr auto ARRAY_SIZE_Y=5;的转换;

此功能可以处理类似函数的宏中包含的常量和基本表达式。由于性能优化,某些宏可能不会显示“…”指示符,但是,灯泡菜单中仍然可以随时使用转换选项。要配置“将宏转换为Constexpr”,请导航到“工具”>“选项”>“文本编辑器”>“C/C++”>“视图”>“可转换为Constexpr的宏”。
将宏转换为Constexpr是我们修复功能中的一个功能。在我们即将发布的博客文章中,我们将深入研究Visual Studio中当前提供的其他修复功能。
GitHub Copilot是一款人工智能编码助手,可以帮助C++开发人员重构代码。它提供了一个简化的重构过程,使其成为代码优化的高效工具。
要使用GitHub Copilot进行重构,首先要确定要重构的代码段。这可以是一个函数、一个类,甚至是一行代码。一旦确定,右键单击所选代码,并请求Copilot帮助进行重构。该命令可以根据您的特定需求进行定制。在生成重构建议后,仔细审查这一点至关重要。进行任何必要的调整,以确保其符合您的编码标准和项目要求。一旦您对提议的重构感到满意,就可以继续在代码中实现更改。
例如,假设您正在使用C++中的一个复杂函数,如“InProcessExampleBrowser.cpp”中的btCreateInProcessExaampleBrowser。为了简化它,你应该突出显示该功能,并向GitHub Copilot请求简化。Copilot建议使用auto进行类型推理,使用nullptr代替0,使用static_cast进行更安全的类型转换,并限制循环变量的范围。这些更改提高了可读性、安全性和可维护性。您可以选择预览,以比较和查看原始代码和建议代码之间的差异。如果您对这些更改感到满意,您可以接受它们,将重构后的代码直接合并到现有的代码库中。

我们鼓励您继续探索Visual Studio中的C++重构功能。您的见解和经验对我们来说是无价的,因此,请在下面的评论部分或通过开发者社区分享您的反馈和建议。您也可以通过Twitter(@VisualC)或电子邮件联系我们visualcpp@microsoft.com.我们总是渴望收到你的来信。
此外,如果您认为有必要或经常使用其他重构功能,我们将非常感谢您的意见。您的建议有助于我们更好地了解您的需求,并不断改进我们的产品。
作者 | Mryam Girmay