使用" set"自动替换赋值运算符。功能

时间:2014-08-29 09:06:51

标签: c++ linux windows qt

我正在将使用Embarcadero RAD Studio构建的C ++ Windows项目移植到带有Qt的Linux。 所以我的代码中有很多声明:

Menu->Enabled = true;

对于Qt,它应该像那样转换:

Menu->setEnabled(true);

所以现在我失去了很多评论代码的时间。有没有办法自动更换?

4 个答案:

答案 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并输入替换字符串。