Есть ли особый способ объявить / определить конструкторы C ++ (и деструкторы) - PullRequest
8 голосов
/ 29 февраля 2012

РЕДАКТИРОВАТЬ: Это обсуждение наилучшей практики в (упрощенном) случае, представленном ниже.Какой бы инструмент, стиль кодирования или что-то еще вы хотели бы предложить, опубликуйте его.Спасибо.

Почему нет специальных способов объявить или определить 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 ]

6 голосов
/ 29 февраля 2012

Вы когда-нибудь слышали о поиске и замене?

Я думаю, что большинство людей используют ex, vim, sed. и т. д .: 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 в классах в частном порядке, затем использую его для списков инициализаторов и т. Д. .

3 голосов
/ 29 февраля 2012

Если имена ваших классов становятся слишком длинными, рассмотрите возможность более широкого использования namespace.

namespace в сочетании с using отлично подходит для создания ваших названий типовтолько настолько многословно, насколько того требует каждый контекст.

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

  }
}
...