Убедитесь, что конструктор производного класса должен вызывать определенный метод базового класса

В классе C ++ (03) у меня есть переменная-член, которая должен присваивать значение при строительстве объекта. Однако только производный класс может вычислить требуемое значение. Как обсуждено в этом посте Требует ли C ++ инициализации членов базового класса из его производного класса?, Я понимаю, что производный класс не может инициализировать член базового класса, но назначение мне достаточно.

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

class Base {
public:
Base() {}
setFoo(unsigned inFoo) { foo = inFoo; }
private:
unsigned foo;
};

class Derived : public Base {
Derived() : Base() {
unsigned desired = ... // do calculations to get the desired value
setFoo(desired);  // --> how to ensure that derived class calls this?
}
};

foo затем используется несколькими другими методами базового класса. Даже если я установлю «флаг» в setFoo(), нет метода «пост-конструктор», где я могу проверить это. Есть несколько других методов в базовом классе, где foo используется. я мог проверьте это там, но это слишком утомительно, подвержено ошибкам и неэффективно.

Мои извинения, если об этом уже спрашивали. Я попытался найти его здесь, прежде чем спросить, выполнив поиск «Убедитесь, что конструктор производного класса должен вызывать определенный метод базового класса» и «Принудительно производный класс для назначения члена базового класса». Я наткнулся на несколько полезных постов Как я могу инициализировать константную переменную базового класса в конструкторе производного класса в C ++? а также Заставить производный класс использовать конструктор базового класса , но они, к сожалению, не отвечают на мой вопрос.

Не могли бы вы предложить мне подходящий подход для решения этой ситуации? Было бы желательно решение для проверки во время компиляции, но если это невозможно, также может помочь проверка во время выполнения. Хотя я не могу использовать C ++ 11 для своей проблемы, я был бы рад изучить также любые решения C ++ 11. Спасибо за внимание.

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

Edit2 Я согласен с ответами о том, что значение должно быть передано в параметре конструктора, и если мне нужно было написать Base с нуля, я бы не попросил такой подход. Проблема в том, что по наследству Base уже имеет несколько параметров конструктора (9), и я надеялся избежать добавления дополнительных (3), «разгрузив» их в теле конструктора. В долгосрочной перспективе, однако, код должен быть реорганизован.

Edit3 Извините за так много правок. я Можно изменить Base класс, как мне нравится, но Derived класс находится в коде клиента, который я не могу контролировать.

3

Решение

Если конструктор производного класса должен вызвать setFoo()Тогда я думаю, что это проблема дизайна. Лучше спроектировать базовый класс так, чтобы его конструктор принимал в качестве аргумента желаемое значение и позволял производному классу передавать вычисленное значение как:

class Base {
public:
Base(unsigned int foo) : m_foo (foo) {}  //define this constructor
private:
unsigned int m_foo; //member data
};

class Derived : public Base {
Derived() : Base(computeValue())
{
}
private:
static unsigned int computeValue() //it may take argument(s)
{
unsigned int desired = ... //do calculations to get the desired value
return desired;
}
};
9

Другие решения

Если для построения объекта требуется значение, оно должно быть параметром для конструктора.

class Base {
public:
Base(unsigned inFoo) { setFoo(inFoo); }
setFoo(unsigned inFoo) { foo = inFoo; }
private:
unsigned foo;
};

class Derived : public Base {
Derived() : Base(compute_desired()) { }

};

Вот compute_desired может быть членом Derivedили просто любая функция, которая выполняет вычисления.

2

Я не думаю, что можно заставить производный класс вызывать метод базового класса в его конструкторе. Возможно, вы сможете форсировать реализацию / вызов через методы в других ответах, но абсолютно точно убедиться, что это сделано в конструкторе Derived, насколько мне известно, невозможно, если только базовый класс не может быть изменен

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector