c++ - 到处都有差异的虚函数

标签 c++ inheritance virtual

考虑这个输出:

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> 等......然后使用这些编译时整数来满足上面评论中所述的规则)?也许避免模板并做其他事情?

最佳答案

可以通过给四个时钟显示类一个bool模板参数来完成。例如

template <bool P>
class DescriptiveTimeDisplay : public TimeDisplay {  // #3
    std::string tell() const override { return "evening"; }
    std::string tellMaybeWithPeriod() const override { return tell() + (P ? "." : ""); }
};

并通过实例化类来控制句点是否显示,例如

std::make_shared<DescriptiveTimeDisplay<true>>()

对于displayCurrentTimefoobarbaz这四个函数,你可以控制它们的显示通过使用不同的 bool 模板参数实例化四个 TimeDisplay 子类来格式化。

关于c++ - 到处都有差异的虚函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31954940/

相关文章:

c# - C# 8 默认接口(interface)实现是否允许多重继承

c# - 使用工厂的动态继承

memory - Javac -Xmx 限制虚拟机使用

c++ - 为客户端知道服务器发送的包有多大的好处

c++ - 如何在不复制的情况下从 vector 中读取值?

python - 强制继承类型的兼容性 (Python)

c++ - 继承虚拟派生类的构造函数。

c++ - 返回不同类型的派生虚函数——指针

c++ - 修改继承的成员变量不会影响基类

php - 类外定义的方法?