Is it possible to change a C++ object's class after instantiation?

后端 未结 16 2157
忘掉有多难
忘掉有多难 2021-02-02 06:50

I have a bunch of classes which all inherit the same attributes from a common base class. The base class implements some virtual functions that work in general cases, whilst eac

16条回答
  •  时光取名叫无心
    2021-02-02 07:02

    I suggest you use the Strategy Pattern, e.g.

    #include 
    
    class IAnnouncer {
    public:
        virtual ~IAnnouncer() { }
        virtual void whoami() = 0;
    };
    
    class AnnouncerA : public IAnnouncer {
    public:
        void whoami() override {
            std::cout << "I am A\n";
        }
    };
    
    class AnnouncerB : public IAnnouncer {
    public:
        void whoami() override {
            std::cout << "I am B\n";
        }
    };
    
    class Foo
    {
    public:
        Foo(IAnnouncer *announcer) : announcer(announcer)
        {
        }
        void run()
        {
            // Do stuff
            if(nullptr != announcer)
            {
                announcer->whoami();
            }
            // Do other stuff
        }
        void expend(IAnnouncer* announcer)
        {
            this->announcer = announcer;
        }
    private:
        IAnnouncer *announcer;
    };
    
    
    int main() {
        AnnouncerA a;
        Foo foo(&a);
    
        foo.run();
    
        // Ready to "expend"
        AnnouncerB b;
        foo.expend(&b);
    
        foo.run();
    
        return 0;
    }
    

    This is a very flexible pattern that has at least a few benefits over trying to deal with the issue through inheritance:

    • You can easily change the behavior of Foo later on by implementing a new Announcer
    • Your Announcers (and your Foos) are easily unit tested
    • You can reuse your Announcers elsewhere int he code

    I suggest you have a look at the age-old "Composition vs. Inheritance" debate (cf. https://www.thoughtworks.com/insights/blog/composition-vs-inheritance-how-choose)

    ps. You've leaked a Derived in your original post! Have a look at std::unique_ptr if it is available.

提交回复
热议问题