Рассмотрим этот вывод:Виртуальные функции с различиями здесь и там
Current time: 6:30 pm
Current time: 18:30
Current time: evening.
Current time: evening (for many it is dinner time, but many eat dinner later).
Обратите внимание, что последние два имеют период, в то время как первые два не. Я получил этот желаемый результат с помощью функции System::displayCurrentTime
члена из приведенной ниже коды:
#include <iostream>
#include <string>
#include <memory>
class TimeDisplay {
public:
virtual std::string tell() const = 0;
virtual std::string tellMaybeWithPeriod() const = 0;
};
class ClockDisplay12Hours : public TimeDisplay { // #1
std::string tell() const override {return "6:30 pm";}
std::string tellMaybeWithPeriod() const override {return tell();}
};
class ClockDisplay24Hours : public TimeDisplay { // #2
std::string tell() const override {return "18:30";}
std::string tellMaybeWithPeriod() const override {return tell();}
};
class DescriptiveTimeDisplay : public TimeDisplay { // #3
std::string tell() const override {return "evening";}
std::string tellMaybeWithPeriod() const override {return tell() + ".";}
};
class CrazyDescriptiveTimeDisplay : public TimeDisplay { // #4
std::string tell() const override {return "evening (for many it is dinner time, but many eat dinner later)";}
std::string tellMaybeWithPeriod() const override {return tell() + ".";}
};
struct System {
static std::shared_ptr<TimeDisplay> timeDisplay;
static std::string timeAsString() {return timeDisplay->tell();}
static std::string timeAsStringMaybeWithPeriod() {return timeDisplay->tellMaybeWithPeriod();}
// #3 and #4 will have a period, the others will not.
static void displayCurrentTime (std::shared_ptr<TimeDisplay> t) {
timeDisplay = t;
std::cout << "Current time: " << System::timeAsStringMaybeWithPeriod() << '\n';
}
static void foo (std::shared_ptr<TimeDisplay>) {} // #1 and #3 will have a period, the others will not.
static void bar (std::shared_ptr<TimeDisplay>) {} // #1, #2, and #4 will have a period, the others will not.
static void baz (std::shared_ptr<TimeDisplay>) {} // #2 will have a period, the others will not
};
std::shared_ptr<TimeDisplay> System::timeDisplay;
int main() {
const std::shared_ptr<TimeDisplay> clocks[] = {std::make_shared<ClockDisplay12Hours>(), std::make_shared<ClockDisplay24Hours>(),
std::make_shared<DescriptiveTimeDisplay>(), std::make_shared<CrazyDescriptiveTimeDisplay>()};
for (std::shared_ptr<TimeDisplay> t : clocks)
System::displayCurrentTime(t);
}
Это не очень грязное, но не отметить, что следующие функции для реализации foo
, bar
, baz
хотят периоды с различными производными классами TimeDisplay
, и на самом деле существует гораздо больше, чем 4 таких производных класса, а также более 3 новых функций-членов. Есть ли более элегантный и элегантный способ справиться с этими предстоящими функциями-членами, чем выписывать новые виртуальные функции для каждого из foo
, bar
, baz
и т. Д., Вместе с которыми будет получать период, а какой нет? Как-нибудь использовать шаблоны (например, переименовать производные классы Derived<0>
, Derived<1>
и т. Д., А затем использовать эти целые числа компиляции, чтобы они соответствовали правилам, изложенным в комментариях выше)? Возможно, вы можете избежать шаблонов и сделать что-то еще?
Просьба уточнить ваш вопрос. –
Как лучше всего реализовать 'foo',' bar', 'baz' и т. Д., Следуя правилам, изложенным в комментариях выше, не повторяя беспорядка, создаваемого' displayCurrentTime'? В противном случае количество новых виртуальных функций будет взрываться. Я оставил 'foo',' bar', 'baz' пустым, потому что беспокоиться только о периоде бизнеса. – prestokeys
Что случилось с помощью следующего кода: 'статической силы displayCurrentTime (станд :: shared_ptr т) { зЬй :: COUT << "Текущее время:" << t-> tellMaybeWithPeriod() << '\ п'; } ' –