Why does C++ not let baseclasses implement a derived class' inherited interface?

前端 未结 5 663
迷失自我
迷失自我 2020-11-29 09:17

Here is what I am talking about

// some guy wrote this, used as a Policy with templates
struct MyWriter {
  void write(std::vector const& dat         


        
5条回答
  •  孤城傲影
    2020-11-29 10:14

    Why doesn't C++ do that? It seems like a natural thing to have.

    Actually, no, it is extremely unnatural thing to have.

    Please note that my reasoning is based on my own understanding of "common sense" and can be fundamentally flawed as a result.

    You see, you have two different methods, first one in MyWriter, which is non virtual and second one in IWriter which is virtual. They are completely different despite "looking" similar.

    I suggest to check this question. The good thing about non-virtual methods is that no matter what you do, as long as they don't call virtual methods, their behavior will never change. I.e. somebody deriving from your class with non-virtual methods will not break existing method by masking them. Virtual methods are designed to be overriden. The price of that is that it is possible to break underlying logic by improperly overriding virtual method. And this is a root of your problem.

    Let's say what you propose is allowed. (automatic conversion to virtual with multiple inheritance) There two possible solutions:

    Solution #1 MyWriter becomes virtual. Consequences: All existing C++ code in the world becomes easy to break via typo or name clash. MyWriter method was not supposed to be overriden initially, so suddenly turning it into virtual will (murphy's law) break underlying logic of MyWriter class when somebody derives from MyOwnClass. Which means that suddenly making MyWriter::write virtual is a bad idea.

    Soluion #2 MyWriter remains static BUUUT it is included temporarily as a virtual method into IWriter, until overriden. At first glance there's nothing to worry about, but let's think about it. IWriter implements some kind of concept you had in mind, and it is supposed to do something. MyWriter implements another concept. To assign MyWriter::write as IWriter::write method you need two guarantees:

    1. Compiler must ensure that MyWriter::write does what IWriter::write() is supposed to do.
    2. Compiler must ensure that calling MyWriter::write from IWriter will not break existing functionality in MyWriter code programmer expects to use elsewhere.

    So, the thing is that compiler cannot guarantee that. Functions have similar name and argument list, but by Murphy's law that means that they're prbably doing completely different thing. (sinf and cosf have same argument list, for example), and it is unlikely that compiler will be able to predict the future and make sure that at no point in development will MyWriter be changed in such way that it will become incompatible with IWriter. So, since machine can't make reasonable decision (no AI for that) by itself, it has to ask YOU, programmer - "What is it you wish to do?". And you say "redirect virtual method into MyWriter::write(). It totally won't break anything. I think.".

    And that's why you must specify which method you want to use manually....

提交回复
热议问题