自动将赋值运算符替换为“;“设置”;功能 我将用BavaDeCo RAD Studio构建我的C++ Windows项目,并用Qt将其移植到Linux。 我的代码中有很多这样的语句: Menu->Enabled = true; Menu->setEnabled(true);

自动将赋值运算符替换为“;“设置”;功能 我将用BavaDeCo RAD Studio构建我的C++ Windows项目,并用Qt将其移植到Linux。 我的代码中有很多这样的语句: Menu->Enabled = true; Menu->setEnabled(true);,c++,linux,windows,qt,C++,Linux,Windows,Qt,对于Qt,它应该这样转换: Menu->Enabled = true; Menu->setEnabled(true); 所以现在我在评论代码上浪费了很多时间。是否有办法自动执行此替换?无论您是在Linux操作系统中,还是在Windows中安装了MinGW或Cygwin,要运行Unix命令,请在要更改代码的基本文件夹中执行以下行: grep -rl "Menu->Enabled = true;" ./ | xargs sed -i "s/Menu->Enabled =

对于Qt,它应该这样转换:

Menu->Enabled = true;
Menu->setEnabled(true);

所以现在我在评论代码上浪费了很多时间。是否有办法自动执行此替换?

无论您是在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"

通常情况下,我会跳进去进行改变,引导一些强迫症,直到构建完成。 为帮助实现这一方法,以下是一些提示:

首先,更改成员的名称,而不仅仅是将其设置为私有。在代码中使该名称成为唯一的标记,至少目前是这样(您可以稍后执行哑全局替换来命名它)

其次,许多这样的行具有完全相同的格式,甚至是相同的变量名,因为它们是由具有统一约定的人编写的,甚至是从其他引用中复制的。这意味着一系列哑搜索/替换命令每次都会找到许多实例。找到一个需要更改的行,并在所有与该行有趣部分匹配的文件中发出全局替换。它不需要完全通用,因为您将对仍然存在的下一个变体进行重复。假点击呢?查找每个具有该名称的字段,即使是在其他类中—如果这很常见,那又怎样?向该类添加一个setXXX成员函数,该函数的工作原理与公共字段相同。现在替代品是无害的,它也可能激发进一步的封装

第三,使用本地git分支,并在每次批量操作后签入更改。这使得以后很容易撤销或修复,或者只是回顾一下它之前所说的内容

如果这不是一个智能指针,而是一个基本指针,那么Source Insight编辑器可能会正确地对字段进行智能重命名。然后使用正则表达式通过函数调用批量更改新的唯一名称

最后,您可能会检查编译器扩展是否可以像Microsoft的那样自动实现属性函数

但是,您需要某种方法使现有语法工作(或者完全自动且正确)。所以这里的想法是:使用一个代理类,该类上定义了一个operator=。大概是这样的:

class C {
public:
   // int value;  -- OLD
   magic_int value;  // NEW
   ⋮
};
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; }

 // ...
< C++的构造函数需要用一个指向封闭类的指针来初始化所有Malue>代码>字段,因为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&));
   ⋮      
};
模板
课堂魔术{
朋友级奥奈特;
ValueT value;//实际备份存储(如果有)。
所有者*所有者;
void(OwnerT::setfunc(const ValueT&));
⋮      
};
现在这样安排,C的指定成员函数,setter,可以做任何需要的事情来协调设置,并且作为其中的一部分,它直接设置原语支持值。支持值存储在magic包装器中,以简化哑getter(隐式转换运算符)

此外,为了更有趣,可以通过模板参数选择集合代码,因此magic包装器不需要在实例中存储实际的setfunc值。这将减少大量的数据开销(指向成员的指针很大),并允许operator=call在编译时内联实际调用


有意思。

如果这是一些小的移植细节,这将妨碍更重要的问题的处理,在这个移植项目中,你也可以考虑推迟这个重构,直到后来,使用这样的方法:

class C {
public:
   // int value;  -- OLD
   magic_int value;  // NEW
   ⋮
};
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需要由所有构造函数初始化,当然包括复制和移动构造函数。

您可以使用Qt Creator find and replace工具自动替换整个项目中的特定模式。按
Ctrl+Shift+F
或选择
Edit>Find/Replace>Advanced Find>Open Advanced Find
。 选择搜索范围,然后按
search&Replace
按钮。然后可以指定要替换的文本


另一个选项是按所选短语的
Ctrl+Shift+R
,然后输入替换字符串。

好吧,我不会回答你的问题,但是过度使用setter通常是不好的。如果有一个公共成员,比如这里的enabled,你不应该为它写一个setter,除非它做的不仅仅是为它提供新的值。(比如检查它是否是有效的新值)老实说,setter可以帮助您调试,因此它可能很有用,但对于逻辑公共成员,我不喜欢它。编写良好的正则表达式替换是最简单的解决方案。我不建议您使用宏(如果可能的话)。编写一个包装类,为Qt/任何您需要的与Qt不兼容的东西使用不同的实现。@juanchopanza setEnabled()由许多基于QWidget的Qt类所有,因此为所有类编写包装会很繁琐。我会使用编译指令。在伯兰时代,一个人