Как предотвратить вывод типа в С++ 03?

C++11 вводит ключевое слово final, которое делает недопустимым наследование от типа.

Есть ли способ добиться аналогичного результата с С++ 03, возможно, сделав некоторые функции-члены private?


person Jared Hoberock    schedule 24.05.2012    source источник
comment
если вы все еще заинтересованы в действительном решении, я могу поделиться им. Дай мне знать.   -  person PiotrNycz    schedule 24.08.2012


Ответы (1)


Есть два решения для C++03:


Первое решение: частный базовый класс виртуального друга с частным конструктором по умолчанию:

Основываясь на этом ответе, с той разницей, что шаблон не используется - таким образом, мы можем сделать виртуальный базовый класс другом "окончательного " класс.

class A;
class MakeAFinal {
private: 
  MakeAFinal() {}   
  // just to be sure none uses copy ctor to hack this solution!
  MakeAFinal(const MakeAFinal&) {}   
  friend class A;
};

class A : private virtual MakeAFinal {
// ...
};

Откровенно говоря, мне это решение не понравилось, потому что оно добавляет лишней виртуальности. Все это можно заключить в макросы, чтобы повысить читабельность и удобство использования:

#define PREPARE_CLASS_FINALIZATION(CN) \
  class CN; \
  class Make##CN##Final { \
    Make##CN##Final() {} \
    Make##CN##Final(const Make##CN##Final&) {} \
    friend class CN; }

#define MAKE_CLASS_FINAL(CN) private virtual Make##CN##Final

PREPARE_CLASS_FINALIZATION(A);
class A : MAKE_CLASS_FINAL(A) {
// ...
};

Второе решение: все конструкторы являются закрытыми (включая конструктор копирования). Экземпляры класса создаются с помощью класса друга:

class AInstance;
class A {
// ...
private:
// make all A constructors private (including copy constructor) to achieve A is final
  A() {}
  A(const A&) {} // if you like to prevent copying - achieve this in AFinal
  // ...
  friend class AInstance;
};
struct AInstance {
  AInstance() : obj() {}
  AInstance(const AInstance& other) : obj(other.obj) {}
  // and all other constructors
  A obj;
};

// usage:
AInstance globalA;
int main() {
  AInstance localA;
  AInstance ptrA = new AInstance();
  std::vector<AInstance> vecA(7);
  localA = globalA;
  *ptrA = localA;
}
person PiotrNycz    schedule 27.08.2012