У меня есть базовый класс:Безопасный способ для инициализации производного класса
class CBase {
public:
virtual void SomeChecks() {}
CBase() {
/* Do some checks */
SomeChecks();
/* Do some more checks */
}
};
и производный класс:
class CDerived : public CBase {
public:
virtual void SomeChecks() { /* Do some other checks */ }
CDerived() : CBase() {}
};
Эта конструкция, кажется, немного странно, но в моем случае это требуется , потому что CBase делает некоторые проверки и CDerived может смешать некоторые проверки между ними. Вы можете видеть это как способ «зацепить» функции в конструкторе. Проблема с этой конструкцией заключается в том, что при построении CDerived сначала создается CBase, и нет осознания CDerived (поэтому перегруженная функция SomeChecks() не называется).
я мог бы сделать что-то вроде этого:
class CBase {
public:
void Init() {
/* Do some checks */
SomeChecks();
/* Do some more checks */
}
virtual void SomeChecks() {}
CBase(bool bDoInit=true) {
if (bDoInit) { Init(); }
}
};
class CDerived : public CBase {
public:
virtual void SomeChecks() { /* Do some other checks */ }
CDerived() : CBase(false) { Init() }
};
Это не очень безопасно, потому что я хочу, конструктор с параметром ложному быть защищены, так что только производные классы могут назвать. Но тогда мне придется создать второй конструктор (который защищен) и заставить его принимать другие параметры (возможно, неиспользуемые, потому что вызывается конструктор, когда Init() не нужно вызывать).
Так что я совершенно застрял здесь.
EDIT На самом деле я хочу что-то вроде этого:
class CBase {
protected:
void Init() { /* Implementation of Init ... */ }
CBase() { /* Don't do the Init(), it is called by derived class */ }
public:
CBase() { Init(); } // Called when an object of CBase is created
};
class CDerived : public CBase {
public:
CDerived() : CBase() { Init(); }
};
Мне кажется, что невозможно иметь 2 конструктора с теми же аргументами, защищаемого и общественности?
Как указано, вызов виртуальных методов в конструкторах не приводит к желаемому поведению. Я думаю, что решение pimpl является наиболее разумным. Тема хорошо освещена в книге Скотта Майера «Эффективная книга на Си ++». – count0
Собственно, это не прыщик. По крайней мере, так называется так. См. Здесь: http://en.wikipedia.org/wiki/Opaque_pointer#C.2B.2B – sbi
На самом деле это так. :-) Прочитайте свою страницу вики. Но хорошая книга по шаблонам проектирования, например, GOF, вероятно, будет лучше. –