Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I work on a very large codebase. We use inheritance and composition. I totally agree that inheritance should be used carefully. However, there are times when composition requires a lot more code and downstream maintenance.

Let's stay I have a base class A. Let's say I have 70 classes that inherit from A.

These classes must serialize/deserialize from disk.

My choice here is that I can add a new data member to A and then update the read/write method in one place, or I add a new data member to all the classes that are derived from A, meaning that I get to update 70 classes. Seriously? Who would think this is a good idea? You'll have to write 70 times as much code... there will be times when that's definitely a very bad idea.

Maybe don't use inheritance. Then give every class its own "Name" data member like std::string c_nName. Every class can have its own function to set the name, or we could use an unencapsulated free function and do things like C. Except then the experts will say things like "well, now you're doing C with classes". Then you get a ticket that the user can enter bad names. You can then figure out some way to validate the names, right? That could be a free function, or maybe write some class called NameValidator. Except now the experts say you're writing C++ like Java. Too many classes, too few classes, too many objects, too few objects, too may free functions, too few free functions.

C++ expert of the month may say X, Y, Z, but look at Microsoft's APIs.

Inheritance is everywhere.

Look at any open source C++ project.

Inheritance is everywhere.

Does that mean that you should make something like:

A

--B : public A

----C : public B

------D : public C

--------E : public D

----------F : public E

Or this:

    A  B
    \  /
     C

Not unless you have a damn good reason. But the point is that inheritance is a valid tool and it can reduce bugs, code duplication, maintenance.

Right tool for the job, yeah? I once read something in the C++ FAQ that said something like "Don't take advice from people who don't understand your business problems."



> Let's stay I have a base class A. Let's say I have 70 classes that inherit from A.

The alternative case is that you have 70 classes that CONTAIN A. You still only have to change A.


Yes, but in my example, in the 70 classes, all the ::Read and ::Write methods must still say:

    a.Read( ... )
    a.Write( ... )
And depending on the use case and design, they also need methods such as:

   A& GetA() { return a; );
   const A& GetA() const { return a; }


The answer is that you retain A as a pure interface and maybe you add a convenience base below A that adds the data member, then you inherit from from the convenience base for your 70 leaf classes. You can also use CRTP for the convenience base, if it's appropriate. You can still avoid confusing interface and implementation inheritance.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: