我正在将使用Embarcadero RAD Studio构建的C ++ Windows项目移植到带有Qt的Linux。 所以我的代码中有很多声明:
Menu->Enabled = true;
对于Qt,它应该像那样转换:
Menu->setEnabled(true);
所以现在我失去了很多评论代码的时间。有没有办法自动更换?
答案 0 :(得分:3)
如果这是一些轻微的移植细节,这会妨碍处理更重要的问题,在这个移植项目中,你也可以考虑推迟这个重构,直到以后,使用类似的方法这样:
class Menu {
public:
class punt_enabled {
Menu *me;
public:
punt_enabled(Menu *meArg);
Menu &operator=(bool flag);
};
punt_enabled Enabled;
// ...
};
// ...
Menu::Menu(...) : Enabled(this) //...
Menu::punt_enabled::punt_enabled(Menu *meArg) : me(meArg) {}
Menu &Menu::punt_enabled(bool flag) { me->setEnabled(flag); return *me; }
// ...
这将让编译器捏命并立即进行此替换,然后你可以回来完成这项工作,使用grep + sed或perl来处理批发更换。
P.S。 punt_enabled需要由所有构造函数初始化,当然包括复制和移动构造函数。
答案 1 :(得分:2)
无论您是在Linux操作系统中,还是在Windows中安装了MinGW或Cygwin,都要运行Unix命令,请在您想要更改代码的基本文件夹中执行以下行:
grep -rl "Menu->Enabled = true;" ./ | xargs sed -i "s/Menu->Enabled = true;/Menu->setEnabled(true);/g"
注意:此命令适用于保存在基本文件夹和子文件夹中的所有文件
编辑:执行以下命令以应用所有使用“ - > Enabled = true”格式或类似的变量:
grep -rl -e "->Enabled = true;" ./ | xargs sed -i "s/->Enabled = true;/->setEnabled(true);/g"
答案 2 :(得分:0)
通常情况下,我会跳进去进行更改,引导一些强迫症,直到构建干净。 为了帮助解决这个问题,这里有一些提示:
首先,更改成员的名称,而不是仅将其设为私有。使名称成为代码中的唯一标记,至少目前是这样(您可以稍后进行愚蠢的全局替换,将其命名为您想要的名称)。
其次,许多这样的行具有完全相同的格式,甚至相同的变量名称,因为它们是由具有统一约定的人编写的,甚至是从其他事件中复制的。这意味着一系列愚蠢的搜索/替换命令会发现每个都出现很多次。找到需要更改的一行,并在与其有趣部分匹配的所有文件中发出全局替换。它不需要完全通用,因为您将重复仍然存在的下一个变体。假命中怎么样?即使在其他类别中找到具有该名称的每个字段 - 如果这是常见的,那么什么?将setXXX成员函数添加到该类,其功能与公共字段相同。现在替换是无害的,它也可能激发进一步的封装。
第三,使用本地git分支并在每次批量操作后检入更改。这样可以在以后轻松撤消或修复,或者只是回过头来查看它之前所说的内容。
如果它不是智能指针而是原始指针,那么Source Insight编辑器可能会对该字段进行适当的智能重命名。然后使用正则表达式使用函数调用批量更改新的唯一名称。
最后,您可以检查编译器扩展是否可用,以及将自动实现属性函数的Microsoft。
但是,您想要一些方法来使现有语法工作(或者完全自动且正确)。所以这里的想法是:使用一个在其上定义了运算符=的代理类。像这样:
class C {
public:
// int value; -- OLD
magic_int value; // NEW
⋮
};
C的构造函数需要使用指向封闭类的指针初始化所有magic
字段,因为C ++没有像Java这样的自动“内部类”。所以
C::C (whatever-it-did-before)
: existing-stuff,
value(this,&C::setter) // for each newly magic field
现在,您希望字段上的赋值语义可以调用setter。所以我们有类似的东西:
int magic_int::operator= (int x)
{
(owner->*setfunc)(x);
}
这意味着magic_int需要owner和setfunc的成员数据,如构造函数中所示。使其成为模板意味着使用CRTP并将其赋予外部类类型以及字段类型:
template<typename OwnerT, typename ValueT>
class magic {
friend class OwnerT;
ValueT value; // the real backing storage, if any.
OwnerT* owner;
void (OwnerT::setfunc(const ValueT&));
⋮
};
现在安排这样,C的指定成员函数,即setter,可以做任何协调设置所需的功能,并且作为其中的一部分,它直接设置原始支持值。支持值存储在魔术包装中,以简化作为隐式转换运算符的哑吸气剂。
此外,为了获得更好的功能,可以通过模板参数完成设置代码选择,因此魔术包装器不需要在实例中存储实际的setfunc值。这将减少大量数据开销(指向成员的指针很大),并允许operator =调用在编译时内联实际调用。
玩得开心。
答案 3 :(得分:0)
您可以使用Qt Creator查找和替换工具来自动替换整个项目中的特定模式。按Ctrl+Shift+F
或选择Edit > Find/Replace > Advanced Find > Open Advanced Find
。
选择搜索范围,然后按Search & Replace
按钮。然后,您可以指定要替换的文本。
另一种选择是在所选短语上按Ctrl+Shift+R
并输入替换字符串。