是否有一种特殊的方式来声明/定义C ++构造函数(和析构函数)

时间:2012-02-29 14:41:37

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

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

为什么没有特殊的方法来声明或定义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;我一直在使用它,虽然不是一个很大的功能,但它让生活更轻松。这是一个简单的例子,但想象一个相当复杂的结构。 (一个方便的副作用也是你在课堂上有一个别名,而不必追踪它的名字。)我错过了什么吗?我真的是唯一一个需要这个的人吗?重点不在于它是否编译,关键在于我已经让它部分地为我工作并且确实有奇迹。直到达到标准...... (这不是合规性讨论。)

2 个答案:

答案 0 :(得分:6)

有没有听说过搜索和替换?

我猜大多数人都使用exvimsed。 etc: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,然后将其用于初始化列表等等。

答案 1 :(得分:3)

如果您的班级名字令人沮丧地啰嗦,请考虑更多地使用namespace

namespaceusing结合使用非常适合使您的类型名称仅像每个上下文要求一样冗长。

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

  }
}