Earlier quoted context omitted.
It's also an extension of basic property rights. An owner of property may will it to whomever he pleases on the event of his passing. It's no different from simply gifting property while alive.
Most discussions of inheritance tax (perhaps particularly discussions where US Americans are involved?) seem to start from this perspective, "the deceased person is being taxed". I find that a little weird. All these weird objections go away like a puff of smoke if you see inheritance tax the other way around: It's a tax on the recipient of the inheritance. Why shouldn't inheritance (or gift!) income be taxed, when a…
Inheritance was invented as a performance hack
261–268 of 268 posts
Re: Inheritance was invented as a performance hack
#262In my experience, 90% of the time people use inheritance but they really only cared about composition, and their language simply does not have any convenient facility to compose types and re-export their methods. With a good type system that includes traits, you almost never need virtual dispatching, as any Rust developer may tell.
Recently experimented a bit with Rust and I found the reverse to be true. You cannot compose types in Rust. You compose behaviors not types. Very important distinction as I found out the hard way. Take the following example I have found on the net: https://play.rust-lang.org/?version=stable&mode=debug&editio... In that example, both the bicycle and the car have the property `speed`. Imagine you have multiple types no…
> You cannot compose types in Rust. You compose behaviors not types.
But I thought in OOP behaviour is type? (Or, IOW, type includes behaviour.) To me, judging only from this, it feels like Rust isn't quite OO... Is it perhaps just not quite finished yet?
Another aspect: That whole "Rust has something called 'monomorphization', which leads to lots of copy-pasting" reinforces that impression. Is this the same problem that C++ tries to overcome by the "select which inherited implementation to use" operator, and other languages by allowing inly single inheritance?
Re: Inheritance was invented as a performance hack
#263I spent way too long trying to figure out how giving your kids your lifetime's earnings would be a performance hack beyond, you know, giving them a head start, before realizing what the headline was talking about.
Re: Inheritance was invented as a performance hack
#264Earlier quoted context omitted.
Why is code reuse your prime example for bad inheritance? What should people do instead?
Interfaces with default implementations are better than classes for a number of reasons, including the diamond problem, and that as systems grow large they almost never fit cleanly into an inheritance tree. Fat pointers with two words, one for an interface vtable and one for the object, work really well.
"The diamond problem" only occurs with multiple inheritance. At a (wild-ass) guess, only a minority of "traditional" (=inheritance-based) OOP languages have that; certainly not all of them. So as far as "the diamond problem" is concerned, interfaces with default implementations are no better than single-inheritance classes.
Re: Inheritance was invented as a performance hack
#265Earlier quoted context omitted.
Doesn’t Parent parent = Child() work because Parent’s constructor is run by implicitly casting ref-to-Child to ref-to-Parent?
I don't think that's enough, because Child() still results in an object that is sizeof(Child). In order to store that object in a variable that is sizeof(Parent) it has to be rejigged somehow. I think what TeeMassive is saying is that this rejigging is a simple truncation because the memory layout of (non virtual) inheritance in C++ is a concatenation of Parent and Child objects. I'm not sure whether this is implemen…
The part about “rejigging” and simple truncation happens before the constructor call when you cast ref-to-Child to ref-to-Parent.
Re: Inheritance was invented as a performance hack
#266Earlier quoted context omitted.
I don't think that's enough, because Child() still results in an object that is sizeof(Child). In order to store that object in a variable that is sizeof(Parent) it has to be rejigged somehow. I think what TeeMassive is saying is that this rejigging is a simple truncation because the memory layout of (non virtual) inheritance in C++ is a concatenation of Parent and Child objects. I'm not sure whether this is implemen…
That’s certainly enough, if you can call a constructor, you don’t have to think about how it works and that the classes are related. The part about “rejigging” and simple truncation happens before the constructor call when you cast ref-to-Child to ref-to-Parent.
Re: Inheritance was invented as a performance hack
#267Earlier quoted context omitted.
That’s certainly enough, if you can call a constructor, you don’t have to think about how it works and that the classes are related. The part about “rejigging” and simple truncation happens before the constructor call when you cast ref-to-Child to ref-to-Parent.
There is no casting of references at all in Parent parent = Child().
Parent p = Child(); calls it by implicitly casting Child& to const Parent&. That’s what happens.
I see that you must have meant this casting step, so indeed the constructor has no control over the rejigging.
Re: Inheritance was invented as a performance hack
#268Earlier quoted context omitted.
There is no casting of references at all in Parent parent = Child().
Sorry for being afk and replying once in a while :/ Parent probably has a copy constructor Parent(const Parent& p) Parent p = Child(); calls it by implicitly casting Child& to const Parent&. That’s what happens. I see that you must have meant this casting step, so indeed the constructor has no control over the rejigging.
Say you have the obvious minimal implementations of
struct Point ...
struct Point3D : public Point ...
And then you do this: Point p3 = Point3D(1.1, 2.2, 3.3);
Point p = p3;
On a 64 bit machine this results in sizeof(p) == 16 and sizeof(p3) == 24. So, at some point someone has to decide how to transform p3's 24 byte representation into p's 16 byte representation.In C++, this happens simply by truncting p3, i.e copying the leading 16 bytes of p3 into p and throwing away the trailing 8 bytes (I'm not sure whether or not this is part of the standard).
This is not the only imaginable way in which this could possibly happen though, which is why I'm saying that the whole process is not sufficiently defined by stating that a reference to child is cast to a reference to parent.