Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inheritance vs aggregation and "has-a" vs "is-a".

In my code I find it useful to use mixin-like inheritance to compose objects with different blocks. I have:

class Name
{
public:
    typedef int32_t value_type;

public:
    // ctors and dtors
    void set_value(value_type value) { value_ = value; }
    const value_type& value() const { return value_; }

private:
    value_type value_;
};

class NamedObject
{
public:
    void set_name(const Name& name) { name_ = name; }
    const Name& name() const { return name_; }

protected:
    // ctors and dtors

private:
    Name name_;
};

And I use this kind of base classes to provide objects with properties with pre-defined non-virtual functionality:

class MyObject: public NamedObject, public HasZlevel {
  // functionality that is not connected with NamedObject and HasZLevel
};

So I decide to treat MyObject as "is-a" NamedObject instead of "has-a" Name. Z-level and Name are properties that will never change during MyObject instance's lifetime. I prefer this to aggregation because of simplified usage in algorithms that are defined just for NamedObjects, or for objects that have HasZLevel interface, i can pass them via NamedObject* or HasZLevel* and be sure that they will not be deleted or appended due to protected dtors and ctors.

Another option is aggregation:

class MyObject
{
public:
    MyObject(const Name& name): name_(name) {}
    void set_name(const Name& name) { named_->set_name(name) }

    // and so on...

private:
    Name name_;
};

To use this I need template algorithm that requires from parameter type to have set_name member function.

Are there any good reasons in my case to abandon my mixin-like design and to use aggregation? Maybe in long-term maintenance and modification?

like image 772
Riga Avatar asked Apr 04 '11 19:04

Riga


1 Answers

Because Multiple Inheritance Sucks.

Here is why I like duct tape programmers. Sometimes, you’re on a team, and you’re busy banging out the code, and somebody comes up to your desk, coffee mug in hand, and starts rattling on about how if you use multi-threaded COM apartments, your app will be 34% sparklier, and it’s not even that hard, because he’s written a bunch of templates, and all you have to do is multiply-inherit from 17 of his templates, each taking an average of 4 arguments, and you barely even have to write the body of the function. It’s just a gigantic list of multiple-inheritance from different classes and hey, presto, multi-apartment threaded COM. And your eyes are swimming, and you have no friggin’ idea what this frigtard is talking about, but he just won’t go away, and even if he does go away, he’s just going back into his office to write more of his clever classes constructed entirely from multiple inheritance from templates, without a single implementation body at all, and it’s going to crash like crazy and you’re going to get paged at night to come in and try to figure it out because he’ll be at some goddamn “Design Patterns” meetup.

And the duct-tape programmer is not afraid to say, “multiple inheritance sucks. Stop it. Just stop.”

The long and short of it is: will this actually help you ship your code faster? Or will it cost more time than it's worth because you'll be debugging multiply inherited classes and stepping through a gordian knot of superclasses in a debugger when some overridden member function chokes on some other member up the inheritance tree?

And yes, I did just write 'chokes on a member'. Multiple inheritance really is that bad.

like image 132
Aphex Avatar answered Oct 30 '22 01:10

Aphex