【问题标题】:Is there a special way to declare/define C++ constructors (and destructors)是否有一种特殊的方式来声明/定义 C++ 构造函数(和析构函数)
【发布时间】:2012-03-19 01:20:28
【问题描述】:

编辑:这是关于下面介绍的(简化)案例中的最佳实践的讨论。无论您想建议什么工具、编码风格或其他内容,都将其发布。谢谢。

为什么没有特殊的方法来声明或定义ctors/dtors而不复制类的名称?这很烦人,尤其是在制作原型并最终更改类名称时。

我的意思是 typedef 是这样的:

struct SomeClassThatDoesSomething {
    typedef SomeClassThatDoesSomething ThisClass;
    ThisClass() { PrepareToDie(); }
    ThisClass(int a) : _a(a) { PrepareToDie(); }
    ThisClass(float a, int b) : _b(a), _a(b) { PrepareToDie(); }
    ThisClass(float a, char * b) : _b(a), _c(b) { PrepareToDie(); }
    ThisClass(char * a, int b) : _c(a), _a(b) { PrepareToDie(); }
    ThisClass(ThisClass &rhs) {  }
    ~ThisClass() {}
    void Burn() {}
    void PrepareToDie() {}
    int _a;
    float _b;
    char *_c;
};

struct SomeDerivedClassThatDoesSomething : public SomeClassThatDoesSomething {
    typedef ThisClass BaseClass;
    typedef SomeDerivedClassThatDoesSomething ThisClass;
    ThisClass(BaseClass &is_not_amused) : BaseClass(is_not_amused) { BaseClass::_a = 1; PrepareToDie(); }
    ThisClass(float a, char * b) : BaseClass(b, a) {}
    ~ThisClass() { BaseClass::Burn(); }
    unsigned int _a; // Different semantics up the tree.
};

//EDIT: Consider this: Enforce export name decoration policy.
#define DLL_API __declspec(dllexport) 
// ... or dllimport - not the point here
#define def_export_struct( name ) struct C##name; typedef C##name *P##name; struct DLL_API C##name 

def_export_struct( SomeOtherClassThatDoesSomething ) : public SomeDerivedClassThatDoesSomething 
{
//...
};
namespace mass_destruction {
    def_export_struct( Int )
    {
    //... (The point is that search and replace gets very unreliable in big projects)
    }
};

它仅适用于 ctors 且仅适用于 MSVC;我一直在使用它,虽然不是一个大功能,但它让生活更轻松。这是一个简单的例子,但想象一个相当复杂的结构。 (一个方便的副作用是你在课堂上有一个别名,而不必跟踪它的名字。) 我错过了什么吗?我真的是唯一需要这个的人吗? 关键不在于它是否可以编译,关键是我已经让它部分地为我工作,它确实很神奇。直到我达到标准...(这不是合规性讨论。)

【问题讨论】:

  • 现代 IDE 具有不错的重构功能(或者有提供它们的插件),因此重命名类变得非常简单。因此,我认为不需要这样的功能。
  • 不太清楚你在问什么。是否存在这样的功能,或者为什么它不存在,或者别的什么?通过说您已经知道这样的功能并且您对合规性不感兴趣,很难知道您还想要什么。
  • @BjörnPollex:C++ 的重构功能通常远远落后于它们的 Java/C# 对应物。除此之外,根本不是每个人都使用 IDE,而且 IDE 的目的几乎不是改进语言不必要
  • @user1240436:任何体面的编辑器都可以让您快速更改类的名称(以及所有用法):我的编辑器/class OldName<enter>my/};<enter>:'y,. s/OldName/NewName/g 如果您想发疯并使用宏,那么您应该得到任何相关问题。
  • Visual Assist 有一个非常好的“重命名”功能。当我的光标位于符号上时,我按 alt+shift+r 并输入新名称。噗。它总共需要 2 秒(而 find&replace 需要 5 秒)。不要让你的代码从你的开发过程中减少 5 秒。

标签: c++ visual-c++ constructor destructor typedef


【解决方案1】:

听说过搜索和替换吗?

我猜大多数人要么使用exvimsed。等:s/search/replace/g 或等同于更改其类的名称,或者不要更改它们,因为缺少此功能而经常感到不安。

您可以使用#define 来合规地执行此操作:

#define THIS_CLASS MyLongClassNameThatIChangeLotsAndLots
class THIS_CLASS{
    THIS_CLASS() { PrepareToDie(); }
    THIS_CLASS(int a) : _a(a) { PrepareToDie(); }
    THIS_CLASS(float a, int b) : _b(a), _a(b) { PrepareToDie(); }
    THIS_CLASS(float a, char * b) : _b(a), _c(b) { PrepareToDie(); }
    THIS_CLASS(char * a, int b) : _c(a), _a(b) { PrepareToDie(); }
    THIS_CLASS(THIS_CLASS &rhs) {  }
    ~THIS_CLASS() {}
};
#undef THIS_CLASS

我同意,令人不安的是缺乏引用类型基类的标准方法——我通常在类中私下 typedef ... base_t,然后将其用于初始化列表等.

【讨论】:

  • 我也使用 sed,但在某些系统中不可用。您的宏没有多大帮助,因为类可能具有不同的构造函数。您甚至不能假设一组最小的公共 ctors。我个人认为不值得花时间。
  • 另一个问题是使用 #pragma push_macro( "THIS_CLASS" ) 和 #pragma pop_macro( "THIS_CLASS" ) 会使宏重新定义变得很丑陋。可行,但更难追踪。我会为不常见的定义保存这样的东西。
  • @UmNyobe 你应该赞成已经包含PrepareToDie()的问题
【解决方案2】:

如果您的班级名称冗长令人沮丧,考虑更多地使用namespace

namespaceusing 结合使用非常适合使您的类型名仅根据每个上下文的要求进行详细说明。

namespace Something
{
  struct Derived : public SomeClass
  {
     Derived() {...etc.}

  }
}

【讨论】:

  • 长名字是故意的。但回到你的答案:这实际上不是让搜索和替换更难吗?它会引入许多重复的名称。
  • @user1240436:它确实使 s/r 更难,是的。我的回答在您编辑后并不真正适用。
  • 它作为一种规划较小项目的方式仍然很有用。
猜你喜欢
  • 2016-12-28
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 2018-06-11
  • 2011-04-03
  • 2010-12-16
  • 2022-08-15
  • 1970-01-01
相关资源
最近更新 更多