Allow a mock class to inherit from a final class

牧云@^-^@ 提交于 2021-01-29 02:50:47

问题


We may declare a final/sealed non-inheritable class using the new C++ keyword final.

class Generator final
{

};

This class may inherit from other, may or may not have virtual (inherited or not). But, how to make it final, yet allow one class to inherit from it?

We mostly need to derive a mock class from real class (with or without late-binding, hence virtual isn't important). How to make it work:

class MockGenerator : Generator{};

But disallow any other inheritance?


回答1:


But, how to make it final, yet allow one class to inherit from it?

That's not possible.

We mostly need to derive a mock class from real class (with or without late-binding, hence virtual isn't important).

If the class is final, you do not need to derive from it. If you do need to derive from it, it is not final. Pick one.

Edit: You can add restrictions to your class, but those come at their own cost to the interface:

class Generator // not final
{
    Generator(); // the only accessible constructor is private

    // whitelist who has access to this constructor
    friend class MockGenerator;
public:
    // no public constructors here except for copy & move

    Generator(Generator&);
    Generator(Generator&&);
    ...

    // provide controlled access to the private constructor
    static Generator make_generator() { return Generator(); }

    // rest of API here
};

This is a class that allows it's factory and MockGenerator specializations to call it's constructor. This comes at the price of blocking trivial construction though.

Old code (no longer compilable):

Generator instance;

New code (enforced by the private constructor):

auto instance = Generator::make_generator();



回答2:


One possibility: use a define for final and define it as empty when generating the test environment.

#ifdef MOCK
#define CLASS_FINAL
#else
#define CLASS_FINAL final
#endif

edit: I agree with the comment of utnapistim: this is not a recommendation, just a technical possibility (but at least better than #define final).




回答3:


If you need to create mock class it for unit-testing, then you can try Typemock Isolator++. Because it easily handles with final classes. You don't even need to change something in you production code (like creation of separate mock class). I've created simple test to demonstrate it:

class Generator final
    {
        public:
            int foo()
            {
                return 0;
            }
    };

    TEST_METHOD(TestFinal)
    {
        Generator* generator = FAKE<Generator>();
        WHEN_CALLED(generator->foo()).Return(1);

        int result = generator->foo();

        Assert::AreEqual(1, result);
    }

Hope it can be useful for you.



来源:https://stackoverflow.com/questions/26465237/allow-a-mock-class-to-inherit-from-a-final-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!