本页内容

C++ 快速修复

如果您使用Clang 代码模型来解析 C++ 文件,则在“Edit ”模式下会获得Clang 修复提示。请使用标准方法激活快速修复,或在代码编辑器左侧边距的上下文菜单中,针对某一行选择适用的修复项。

可对 C++ 代码应用以下类型的快速修复:

  • 更改二进制操作数
  • 简化 if 和 while 条件(例如,将声明移出 if 条件)
  • 修改字符串(例如,将字符串编码设置为 Latin-1、标记字符串为可翻译,以及将符号名称转换为驼峰式命名法)
  • 创建变量声明
  • 创建函数声明和定义

下表总结了根据光标位置,C++ 代码可用的快速修复功能。

选中的代码块

快速修复描述
赋值给局部变量添加一个局部变量,用于存储函数调用的返回值或new表达式的结果。例如,将以下代码重写为
QString s;
s.toLatin1();

QString s;
QByteArray latin1 = s.toLatin1();

,以及

new Foo;

以及

Foo * localFoo = new Foo;

默认情况下,Qt Creator 在创建变量时使用auto 变量类型。若要以变量的实际类型为其命名,请选择“Preferences ” > “C++ ” > “Quick Fixes ”,并取消勾选“Use type "auto" when creating new variables ”。

此功能也适用于函数调用。

提取函数将选定的代码移至一个新函数中,并用对新函数的调用替换该代码块。在“Extract Function Refactoring ”对话框中输入函数名称。
将常量提取为函数参数将所选字面量及其所有出现位置替换为函数参数newParameter ,该参数的默认值即为原始字面量。

当光标位于类定义上时,可使用以下快速修复功能。

快速修复描述
添加 #include在项目文件中添加#include 指令,以便使用该类。
添加 #include 和项目依赖在项目文件中添加#include 指令和包依赖关系,以便使用一个未知的Qt类。
添加定义根据前向声明创建一个空类或结构体定义。
为成员函数创建实现一次性为所有成员函数生成实现。在“Member Function Implementations ”对话框中,指定成员函数是内联生成还是在类外部生成。
生成构造函数为类生成构造函数。
生成缺失的Q_PROPERTY 成员Q_PROPERTY 中添加缺失的成员:
  • read 函数
  • write 函数,如果存在 WRITE
  • onChanged 信号,则添加一个名为
  • 名称为m_<propertyName>
插入基类的虚函数将声明及其相应的定义插入类内部、类外部或实现文件(如果存在)中。有关详细信息,请参阅“插入虚函数”
移动所有函数定义将所有函数定义移至实现文件或类外部。例如,重写
class Foo
{
  void bar()
  {
      // do stuff here
  }
  void baz()
  {
      // do stuff here
  }
};

class Foo
{
  void bar();
  void baz();
};

void Foo::bar() {
    // do stuff here
}

void Foo::baz() {
    // do stuff here
}
将类移至一组专用的源文件中将类移至单独的头文件和源文件中。有关详细信息,请参阅“将类移至单独的文件”
根据声明顺序重新排列成员函数定义.cpp 文件中的方法定义重新排序,使其遵循相应.h 文件中方法声明的顺序。

类成员

当光标位于类定义中的成员变量上时,可使用以下快速修复功能。

快速修复描述
生成常量Q_PROPERTY 和缺失的成员生成常量Q_PROPERTY 并向其中添加缺失的成员。
生成获取器为成员变量创建一个获取器成员函数。
生成获取器和设置器为成员变量创建获取器和设置器成员函数。
创建获取器和设置器成员函数为成员变量同时生成获取器和设置器成员函数,或者仅生成获取器或设置器。
生成Q_PROPERTY 和缺失的成员生成Q_PROPERTY 并向其中添加缺失的成员。
生成Q_PROPERTY 并添加缺失成员(含重置函数)生成Q_PROPERTY 并向其中添加缺失的成员,同时包含一个额外的reset 函数。
生成设置器为成员变量创建一个设置器成员函数。

控制语句

快速修复描述
添加大括号在 if 子句或 do、while 或 for 循环中添加大括号。例如,重写一个 if 子句
if (a)
    b;
else
    c;

if (a) {
    b;
} else {
    c;
}

将 do 循环重写为

do
    ++i;
while (i < 10);

do {
    ++i;
} while (i < 10);

重写一个 while 循环

while (i > 0)
    --i;

while (i > 0) {
    --i;
}

重写 for 循环

for (int i = 0; i < 10; ++i)
    func(i);

for (int i = 0; i < 10; ++i) {
     func(i);
}
删除大括号从仅包含一条语句的代码块中移除大括号。
完善 switch 语句为类型为enum 的switch语句添加所有可能的case。
将声明移出条件语句将声明移出 if 或 while 条件,以简化条件。例如,重写
if (Type name = foo()) {}

Type name = foo;
if (name) {}
优化 for 循环将后递增运算符重写为前递增运算符,将后递减运算符重写为前递减运算符。此外,还将 for 循环条件中除字符串或数值字面量及 id 表达式以外的内容移至初始化表达式中。例如,重写
for (int i = 0; i < 3 * 2; i++)

for (int i = 0, total = 3 * 2; i < total; ++i)

函数声明或定义

快速修复描述
添加定义...在头文件(类内部或外部)或实现文件中,为函数声明插入定义占位符。对于自由函数,会在函数声明之后或实现文件中插入定义。在可能的情况下,会尽量缩短限定名,而不是始终将其完全展开。

例如,将

Class Foo {
    void bar();
};

为(类内部)

Class Foo {
    void bar() {

    }
};

as(类外部)

Class Foo {
    void bar();
};

void Foo::bar()
{

}

as(在实现文件中)

// Header file
Class Foo {
    void bar();
};

// Implementation file
void Foo::bar()
{

}
添加Function 声明将与成员函数定义相匹配的成员函数声明插入到类声明中。该函数可以是publicprotectedprivatepublic slotprotected slotprivate slot
应用更改通过在编辑函数签名时检查匹配的声明或定义,并将更改应用到匹配的代码中,从而保持函数声明与定义的同步。

当此修复功能可用时,会显示一个灯泡图标:灯泡图标

将函数调用转换为 Qt 元方法调用将可调用的函数调用转换为元方法调用。这通常适用于信号和槽,也适用于显式标记为Q_INVOKABLE 的函数。例如,对于以下类:
class Foo : public QObject
{
    Q_OBJECT
public:
    explicit Foo(QObject *parent = nullptr);

    Q_SLOT void pubBar(int i);

private:
    Q_INVOKABLE void bar(int i, const QString &c);
};

重写

Foo::Foo(QObject *parent)
    : QObject{parent}
{
    this->bar(42, QString("answer"));
}

重写为

Foo::Foo(QObject *parent)
    : QObject{parent}
{
    QMetaObject::invokeMethod(this, "bar", Q_ARG(int, 42), Q_ARG(QString, QString("answer")));
}

该快速修复方案也适用于类外部的可调用方法,只要这些方法在调用位置是可见的即可。例如,它会重写

Foo f;
f.pubBar(123);

Foo f;
QMetaObject::invokeMethod(&f, "pubBar", Q_ARG(int, 123));
将定义移至此处将现有函数定义移动到其声明处。
移动函数定义将函数定义移动到实现文件中、移出类之外,或移回其声明处。例如,重写
class Foo
{
  void bar()
  {
      // do stuff here
  }
};

class Foo
{
  void bar();
};

void Foo::bar() {
    // do stuff here
}
将函数文档移至声明/定义处将函数的文档注释移至其声明与定义之间。

标识符

快速修复描述
为未声明或前向声明的标识符添加 #include在当前文件中添加#include 指令,以便使用该符号的定义。
添加类成员如果正在初始化的类成员尚未声明,则为其添加成员声明。如果Qt Creator 无法自动检测该成员的数据类型,则必须手动添加。
添加定义为静态数据成员插入定义骨架。
添加前向声明为未声明的标识符操作添加前向声明。
转换为驼峰式命名将符号名称转换为驼峰式命名法,即名称的各个部分不使用分隔符连接,且每个部分的首字母大写。例如,将an_example_symbol 重写为anExampleSymbol ,将AN_EXAMPLE_SYMBOL 重写为AnExampleSymbol

数字字面量

快速修复描述
转换为十进制将整数字面量转换为十进制表示法
转换为十六进制将整数字面量转换为十六进制表示形式
转换为八进制将整数字面量转换为八进制表示法

运算符

快速修复描述运算符
使用 || 重写条件根据德摩根定律重写表达式。例如,将
!a && !b

!(a || b)
&&
使用运算符重写将表达式重写为其否定形式,并使用逆运算符。例如,将
  • a op b

    !(a invop b)
  • (a op b)

    !(a invop b)
  • !(a op b)

    (a invob b)
<=<>>===!=
拆分 if 语句将一个 if 语句拆分为多个语句。例如,重写
if (something && something_else) {
}

if (something) {
   if (something_else) {
   }
}

,以及

if (something || something_else)
    x;

以及

if (something)
    x;
else if (something_else)
    x;
&&||
交换操作数使用逆运算符将表达式按逆序重写。例如,将
a op b

b flipop a
<=<>>===!=&&||

字符串字面量

快速修复描述
追加运算符将字符串字面量运算符(QByteArrayLiteralQLatin1CharQLatin1StringQStringLiteral ),例如"_ba""_L1" ,添加到字符串字面量中。
转换为字符字面量将单字符字符串字面量转换为字符字面量,但存在一些特殊情况。例如,
"a"
"'"
"\n"
"\""

将被转换为

'a'
'\''
'\n'
'"'
转换为 Objective-C 字符串字面量如果文件类型为 Objective-C(++),则将字符串字面量转换为 Objective-C 字符串字面量。例如,会重写以下字符串
"abcd"
QLatin1String("abcd")
QLatin1Literal("abcd")

@"abcd"
转换为字符串字面量将字符字面量转换为字符串字面量,但存在一些特殊情况。例如,
'a'
'\''
'\n'
'"'

将转换为

"a"
"'"
"\n"
"\""
QByteArrayLiteral()包裹将字符串转换为字节数组。例如,将
"abcd"

QByteArrayLiteral("abcd")
用QLatin1Char()包裹将字符的编码设置为Latin-1,除非该字符已被QLatin1CharQT_TRANSLATE_NOOP 、tr、trUtf8、QLatin1Literal或QLatin1String 所包围。例如,将
'a'

QLatin1Char('a')
使用 QLatin1String() 进行封装将字符串的编码设置为Latin-1,除非该字符串已被QLatin1CharQT_TRANSLATE_NOOP 、tr、trUtf8、QLatin1Literal或QLatin1String 所包围。例如,将
"abcd"

QLatin1String("abcd")
将字符串字面量转为 UTF-8 转义形式将字符串字面量中的非ASCII字符转义为十六进制转义序列。字符串字面量将按UTF-8格式处理。
标记为可翻译将字符串标记为可翻译。例如,根据可用选项,将"abcd" 重写为以下选项之一:
tr("abcd")
QCoreApplication::translate("CONTEXT", "abcd")
QT_TRANSLATE_NOOP("GLOBAL", "abcd")
将字符串字面量解逃为 UTF-8将字符串字面量中的八进制或十六进制转义序列还原。字符串字面量按 UTF-8 处理。

using 指令

快速修复描述
删除全局作用域中所有using namespace 的出现,并相应调整类型名称删除全局作用域中所有using namespace 的实例,并相应调整类型名称。
删除using namespace 并相应调整类型名称删除局部作用域中所有using namespace 的实例,并相应调整类型名称。

其他

快速修复描述激活
添加局部声明如果赋值式右侧的类型已知,则添加受赋值的类型。例如,将
a = foo();

Type a = foo();

其中 Type 是foo()

指派对象
添加项目依赖项将缺失的 Qt 文件的包依赖关系添加到项目文件中。Qt 类的 #include 语句
将 connect() 转换为 Qt 5 风格将 Qt 4 XML 风格的 `QObject::connect()` 转换为 Qt 5 风格。QObject::connect()(Qt 4 风格)
将注释转换为 C/C++ 风格将 C 风格注释转换为 C++ 风格注释,反之亦然。该工具会尽量保留美观的排版,并考虑 Doxygen 和 qdoc 的格式要求,但您可能需要对转换结果进行整理。代码注释
转换为指针将选中的栈变量转换为指针。例如,将
QByteArray foo = "foo";
foo.append("bar");

QByteArray *foo = new QByteArray("foo");
foo->append("bar");

此操作仅限于函数作用域内进行。此外,目前尚未遵循指针和引用相关的编码规范。

栈变量
转换为栈变量将选定的指针转换为栈变量。例如,将以下代码重写为
QByteArray *foo = new QByteArray("foo");
foo->append("bar");

QByteArray foo("foo");
foo.append("bar");

此操作仅限于函数作用域内进行。此外,目前尚未遵循指针和引用相关的编码规范。

指针变量
重新格式化指针或引用根据当前项目的代码样式设置,重新格式化包含指针或引用声明的代码。如果未打开任何项目,则使用当前的全局代码样式设置。

例如,将以下代码重写为

char*s;

char *s;

当应用于选择集时,选择集中所有符合条件的声明都会被重写。

包含指针或引用的声明,以及包含此类声明的选择项
拆分声明将一个简单声明拆分为多个声明。例如,重写
int *a, b;

int *a;
int b;
类型名或变量名
使用“下一项/上一项”参数切换将参数在参数列表中向上或向下移动一位。函数声明或定义中的参数

另请参 阅“应用快速修复”“查找符号”“重命名符号”“指定快速修复设置”、“QML 快速修复”和“快速修复”

Copyright © The Qt Company Ltd. and other contributors. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.