Why does C++ constructor accept incorrect type as a parameter? - c++

The title pretty much says it all. I have a constructor
Brain::Synapse::Synapse(Neuron *new_neuron);
But when I pass it an incorrect type (a member from a vector like this)
std::vector<Motor_Neuron*> neurons;
Synapse *new_synapse = new Synapse(neurons[neuron_index]);
It works just fine (and that's the issue). Motor_Neuron is a derived class from Neuron, so I suspect this is why. My problem ultimately is that I need some Synapses to be connected to Neurons and others to Motor_Neurons. The Synapse class has a member that is a pointer to the "connected neuron". I have been trying to overload the constructor, but I don't think that will work, because if one of the constructors accepts the wrong type I don't see how the correct constructor will be selected.

If Motor_Neuron inherits from Neuron, then it isn't an incorrect type. That is the entire basis of inheritance; that inherited classes are their parent classes, just with some extra bits and pieces.
It sounds more like you need to work on your application's class hierarchy. The SOLID principles are great guidelines. The relevant one is the Liskov Substitution Principle which states that “objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.” If your Motor_Neuron cannot fill the role of a Neuron, then it should not inherit from it. If it needs to leverage some functionality from a Neuron, maybe have it have a Neuron as a member and use its functions from there.
There are work arounds with creating a Motor_Neuron constructor and deleting it or throwing an exception, but I don't really condone trying to fix the symptom like that, and instead get to the source; your design.

Related

Is my diamond inheritance compiler error impossible to solve?

Structure
I have created a diamond inheritance problem. It looks like this
I thought I understood virtual inheritance fairly well, however I now think that I have slightly missunderstood it.
It was my understanding that virtual inheritance tells the compiler to ignore any member data or functions which appear twice with the same name as a result of a diamond inheritance pattern, thus only the "non virtual" inherited components would be contained in the derived class.
However I now think this understanding of how the compiler implements inheritance is wrong.
I have 2 diamond inheritance patterns in my inheritance hierarchy. They are marked using the notes included.
I have also added some notes to show where I attempted to put virtual to resolve the compiler errors, but a different compiler error resulted. The note briefly describes what the problem was. (See the final section of this question if you are interested)
Useage
The intended usage is a std::list<GUIObject*> is created. All gui objects should be able to Draw and ProcessEvent. Not all gui objects will contain the container contained inside SingleLineBuffer.
Buffer and FileBuffer inherit from SingleLineBuffer to change how the container inside SingleLineBuffer behaves. (FileBuffer actually only added new file IO functions.)
One could create an instance of one of the buffers, however I don't in the context I am working with.
One cannot create an instance of any of the abstract GUI* classes. Thinking about it, there should probably be an additional abstract base class below GUIMultilineTextEntry which inherits from FileBuffer.
The actual objects that the user may create an instance of are Label, Inputbox and Textbox. I intend to add more in the future, such as a multiline label. This would have to inherit from a base class which inherited from Buffer and GUITextObject, probably.
This inheritance structure quickly became quite complicated. I wrote it as I went along, guided by what my code was instructing me to do. For example, I wrote a Textbox class, then said "the container in Textbox is essentially the same as the container in Label, therefore they should inherit from a common object". The difference was that a Textbox has file IO, an additional inheritance step is dictated, and a Textbox can contain the new line character in the container, so an additional inheritance step is dictated here too.
Questions
Can this inheritance problem be resolved?
Which classes should inherit virtually from which other classes.
My attempts
No virtual inheritance
Compiler error: (multiple versions of)
error: request for member ‘Size’ is ambiguous
status_text << "Save: " << static_cast<Textbox*>(current_window._guiobject_map_.at("textbox"))->GetFilename() << ", " << static_cast<Textbox*>(current_window._guiobject_map_.at("textbox"))->Size() << " bytes";
Size is defined in SingleLineBuffer. It is a non-virtual function, as the container exists only in SingleLineBuffer, and therefore Size is written to work correctly for both Buffer and FileBuffer.
Break diamond 1: Put virtual between GUITextObject and GUITextEntry to stop Size being "pulled down via GUITextObject" before it is overridded in Buffer. (Blue mark)
Compiler error (1):
error: no matching function for call to ‘GUITextObject::GUITextObject()’
I can fix this by calling the required constructor from GUIMultilineTextEntry. I don't understand why this is needed. (Second Question) Fix shown below:
GUIMultilineTextEntry(const FontTextureManager& ftm, const int width, const int height)
: GUITextEntry(ftm, width, height)
, GUITextObject(ftm, width, height) // also call the constructor for the class which was inherited virtual in the previous step
{ ...
This same fix is needed in Inputbox and Textbox.
However this results in a further error
error: cannot convert from pointer to base class ‘GUIObject’ to pointer to derived class ‘Textbox’ via virtual base ‘GUITextObject’
static_cast<Textbox*>(current_window._guiobject_map_.at("textbox"))->SetFilename(filename);
I believe I could resolve this by using dynamic_cast instead of static_cast, however I am not sure this is a good idea as I have heard that dynamic casting can slow down code significantly.
Break diamond 1, second attempt:
I made a second attempt at resolving the problem by inheriting virtually between Buffer and SingleLineBuffer. (See red dot) However when I did this the compiler error changed to
error: no unique final overrider for ‘virtual void SingleLineBuffer::SetText(const string&)’ in ‘Textbox’
My guess is this is equivalent to the compiler telling me "you overrided some functions in Buffer by inheriting, but you inherited virtually, and the functions you have overridden are also present in a derived class via non-virtual inheritance, so I don't know which one should take precidence" - but this really is a guess.
I tried similar things to break diamond 2 but encountered similar compiler errors.
Since this is now quite a long question, I will not list all the details of that attempt here.
The answer to the titular question is no. (Normally the MCVE comes in the question, but I guess here it really is an answer.) As for the detailed questions:
An inheritance needs to be virtual if it is directly from the common ancestor (the "top of the diamond") of which you want only one copy in the complete object. (So here, you need 4 virtuals, just by counting converging arrows.)
You need to call the constructor of every virtual base in every concrete class, because the most-derived class initializes them directly.
You really can't use static_cast from (or via, as it says) a virtual base, since the class layout varies between instances (because of differing other base classes). However, the cost of one dynamic_cast per GUI operation is surely immeasurable.
Your "unique final overrider" error analysis is probably right, but the answer is more cowbellvirtual.

Inheritance in C++ multiple class issue

just a very simple question regarding inheritance in c++.
let's say I have a few classes.
Class A inherits from class B and from class C.
I want to make class D inherit from class A , but the functionality of class C is breaking my code.
Is it possible to somehow exclude class C when I inheriting from class A in class D?
edit:
#Quentin
I'm using SFML and class A inherits from the sf::NonCopyable class. Class A is the SceneNode class on which the hierarchy for all entities/objects in the game world is based. I was making a "TileEngine" class that produces instances of "TileLayer" objects and I wanted the TileLayers to inherit from SceneNode so that I can pass drawing calls onto them through the hierarchy but since they're non copyable I can't fit them into a container and iterate through them in the TileEngine class.
But I think you're right, it doesn't truly break the code. I think I'll just need to add a few variables and come up with a book keeping system to make it work.
I was just curious if what I asked was possible since it'd be an easy solution and I don't know all the ins and outs of using inheritance yet, so even though it seemed unlikely I decided to check. Thx for the replies I think I'll be able to adapt the code on my own.
Nope.
Your A is both a B and a C.
If D cannot be a C, then it cannot be an A either.
Maybe use composition instead?
Update based on your specific case: There are a couple of ways that you can sort this out.
First off, does a SceneNode really need to be non-copyable, and if so, why? If this is a pure design decision, it is now apparent that it was the wrong one, since you're now in need of a copyable SceneNode. If the decision is technical (for example, there is bookkeeping data that is hard to clone correctly), you can try solving that problem. Failing that...
Could your SceneNode be movable instead? Move semantics are generally simpler than copy semantics to implement, and standard containers are perfectly happy with movable-only values. But even in that case...
Could your SceneNode be a simple interface instead? You only mention being able to call a drawing function. This does not sound related to any copying business, so maybe an interface with a pure virtual draw function is all you need. Otherwise...
If you really can't budge these requirements (at which point I would be surprised, but let's pretend), you can simply use a container of std::unique_ptr<TileLayer>. These don't require anything from their pointee, and can be stored in containers at will.
And then there's a whole 'nother batch of techniques that could fit you case. Don't forget that OOP and inheritance are just one way to crack that nut, but C++ offers many more tools and techniques besides it. But first, make it work :)

Is using an empty base class justified in this example?

I'm writing a Window class which propagates different types of events, listed in
enum Event {WINDOW_ClOSE=0x1, WINDOW_REDRAW=0x2, MOUSE_MOVE=0x4, ...};
to objects which have registered for notification with the window. For each type of event, I have an abstract class which any object must extend in order to allow notification. To react to, say, a MOUSE_MOVE event, my object would inherit from MouseMoveListener, which has a process_mouse_move_event() method which is called by Window. Listening to many events can be combined by extending multiple of these classes, which all inherit from the EventListener base class. To register an object, I would call
void Window::register(EventListener* object, int EventTypes)
{
if(EventTypes&WINDOW_CLOSE)
/* dynamic_cast object to WindowCloseListener*, add to internal list of all
WindowCloseListeners if the cast works, else raise error */
if(EventTypes&MOUSE_MOVE)
/* dynamic_cast object to MouseMoveListener*, add to internal list of all
MouseMoveListeners if the cast works, else raise error */
...
}
This works fine, but my gripe is that EventListener is completely empty and that seems code smelly to me. I know I could avoid this by removing EventListener altogether and having a separate Window::register for each type of event, but I feel that this would blow up my interface needlessly (especially since methods other than register might crop up with the same problem). So I guess I am looking for answers that either say:
"You can keep doing it the way you do, because ..." or
"Introduce the separate Window::register methods anyway, because ..." or of course
"You are doing it all wrong, you should ...".
EDIT:
From the link in Igors comment: What I do above only works if there is at least one virtual member in EventListener for example a virtual destructor, so the class is not technically completely empty.
EDIT 2:
I prematurely accepted n.m.'s solution as one of the type "I'm doing it all wrong". However, it is of the second type. Even if I can call EventListener->register(Window&) polymorphically, Window needs to implement a highly redundant interface (in terms of declared methods) that allows EventListeners to register for selective notification. This is equivalent to my alternative solution described above, only with the additional introduction of the EventListener class for no good reason. In conclusion, the canonical answer seems to be:
Don't do dynamic_cast + empty base class just to avoid declaring many similar functions, it will hurt you when maintaining the code later. Write the many functions.
EDIT 3:
I found a solution (using templates) which is satisfactory for me. It does not use an empty base class any more and it does not exhibit the maintenance problem pointed out by n.m.
object->registerWindow (this, EventTypes);
Of course you need to implement registerWindow for all EventListener heirs. Let them check for event types which are relevant to them.
UPDATE
If this means you need to redesign your code, then you need to redesign your code. Why is it so? Because dynamic_cast is not a proper way to do switch-on-types. It is not a proper way because every time you add a class in your hierarchy, you need to go over and possibly update all switches-by-dynamic-cast in your old code. This becomes very messy and unmaintainable very quickly, and this is exactly the reason why virtual functions were invented.
If you do your switch-on-types with virtual functions, every time you change your hierarchy you have to do... nothing. The virtual call mechanism will take care of your changes.
This is what I ended up doing:
template <int EventType> void register_(EventListener<EventType> Listener)
{
// do stuff with Listener, using more templates
};
It turned out that static polymorphism was better suited for my needs - I just wanted to avoid writing
register_mouse_motion_event(...)
register_keyboard_event(...)
and so on. This approach also nicely eliminates the need for an empty base class.

Why do Boost Parameter elected inheritance rather than composition?

I suppose most of the persons on this site will agree that implementation can be outsourced in two ways:
private inheritance
composition
Inheritance is most often abused. Notably, public inheritance is often used when another form or inheritance could have been better and in general one should use composition rather than private inheritance.
Of course the usual caveats apply, but I can't think of any time where I really needed inheritance for an implementation problem.
For the Boost Parameter library however, you will notice than they have chosen inheritance over composition for the implementation of the named parameter idiom (for the constructor).
I can only think of the classical EBO (Empty Base Optimization) explanation since there is no virtual methods at play here that I can see.
Does anyone knows better or can redirect me to the discussion ?
Thanks,
Matthieu.
EDIT: Ooopss! I posted the answer below because I misread your post. I thought you said the Boost library used composition over inheritance, not the other way around. Still, if its usefull for anyone... (See EDIT2 for what I think could be the answer for you question.)
I don't know the specific answer for the Boost Parameter Library. However, I can say that this is usually a better choice. The reason is because whenever you have the option to implement a relationship in more than one way, you should choose the weakest one (low coupling/high cohesion). Since inheritance is stronger than composition...
Notice that sometimes using private inhertiance can make it harder to implement exception-safe code too. Take operator==, for example. Using composition you can create a temporary and do the assignment with commit/rollback logic (assuming a correct construction of the object). But if you use inheritance, you'll probably do something like Base::operator==(obj) inside the operator== of the derived class. If that Base::operator==(obj) call throws, you risk your guarantees.
EDIT 2: Now, trying to answer what you really asked. This is what I could understand from the link you provided. Since I don't know all details of the library, please correct me if I'm wrong.
When you use composition for "implemented in terms of" you need one level of indirection for the delegation.
struct AImpl
{
//Dummy code, just for the example.
int get_int() const { return 10; }
};
struct A
{
AImpl * impl_;
int get_int() const { return impl->get_int(); }
/* ... */
};
In the case of the parameter-enabled constructor, you need to create an implementation class but you should still be able to use the "wrapper" class in a transparent way. This means that in the example from the link you mentioned, it's desired that you can manipulate myclass just like you would manipulate myclass_impl. This can only be done via inheritance. (Notice that in the example the inheritance is public, since it's the default for struct.)
I assume myclass_impl is supposed to be the "real" class, the one with the data, behavior, etc. Then, if you had a method like get_int() in it and if you didn't use inheritance you would be forced to write a get_int() wrapper in myclass just like I did above.
This isn't a library I've ever used, so a glance through the documentation you linked to is the only thing I'm basing this answer on. It's entirely possible I'm about to be wrong, but...
They mention constructor delegation as a reason for using a common base class. You're right that composition could address that particular issue just as well. Putting it all in a single type, however, would not work. They want to boil multiple constructor signatures into a single user-written initialization function, and without constructor delegation that requires a second data type. My suspicion is that much of the library had already been written from the point of view of putting everything into the class itself. When they ran into the constructor delegation issue they compromised. Putting it into a base class was probably closer to what they were doing with the previous functionality, where they knew that both interface and implementation aspects of the functionality would be accessible to the class you're working with.
I'm not slamming the library in any way. I highly doubt I could put together a library like this one in any reasonable amount of time. I'm just reading between the lines. You know, speaking from ignorance but pretending I actually know something. :-)

Extending an existing class like a namespace (C++)?

I'm writing in second-person just because its easy, for you.
You are working with a game engine and really wish a particular engine class had a new method that does 'bla'. But you'd rather not spread your 'game' code into the 'engine' code.
So you could derive a new class from it with your one new method and put that code in your 'game' source directory, but maybe there's another option?
So this is probably completely illegal in the C++ language, but you thought at first, "perhaps I can add a new method to an existing class via my own header that includes the 'parent' header and some special syntax. This is possible when working with a namespace, for example..."
Assuming you can't declare methods of a class across multiple headers (and you are pretty darn sure you can't), what are the other options that support a clean divide between 'middleware/engine/library' and 'application', you wonder?
My only question to you is, "does your added functionality need to be a member function, or can it be a free function?" If what you want to do can be solved using the class's existing interface, then the only difference is the syntax, and you should use a free function (if you think that's "ugly", then... suck it up and move on, C++ wasn't designed for monkeypatching).
If you're trying to get at the internal guts of the class, it may be a sign that the original class is lacking in flexibility (it doesn't expose enough information for you to do what you want from the public interface). If that's the case, maybe the original class can be "completed", and you're back to putting a free function on top of it.
If absolutely none of that will work, and you just must have a member function (e.g. original class provided protected members you want to get at, and you don't have the freedom to modify the original interface)... only then resort to inheritance and member-function implementation.
For an in-depth discussion (and deconstruction of std::string'), check out this Guru of the Week "Monolith" class article.
Sounds like a 'acts upon' relationship, which would not fit in an inheritance (use sparingly!).
One option would be a composition utility class that acts upon a certain instance of the 'Engine' by being instantiated with a pointer to it.
Inheritance (as you pointed out), or
Use a function instead of a method, or
Alter the engine code itself, but isolate and manage the changes using a patch-manager like quilt or Mercurial/MQ
I don't see what's wrong with inheritance in this context though.
If the new method will be implemented using the existing public interface, then arguably it's more object oriented for it to be a separate function rather than a method. At least, Scott Meyers argues that it is.
Why? Because it gives better encapsulation. IIRC the argument goes that the class interface should define things that the object does. Helper-style functions are things that can be done with/to the object, not things that the object must do itself. So they don't belong in the class. If they are in the class, they can unnecessarily access private members and hence widen the hiding of that member and hence the number of lines of code that need to be touched if the private member changes in any way.
Of course if you want to access protected members then you must inherit. If your desired method requires per-instance state, but not access to protected members, then you can either inherit or composite according to taste - the former is usually more concise, but has certain disadvantages if the relationship isn't really "is a".
Sounds like you want Ruby mixins. Not sure there's anything close in C++. I think you have to do the inheritance.
Edit: You might be able to put a friend method in and use it like a mixin, but I think you'd start to break your encapsulation in a bad way.
You could do something COM-like, where the base class supports a QueryInterface() method which lets you ask for an interface that has that method on it. This is fairly trivial to implement in C++, you don't need COM per se.
You could also "pretend" to be a more dynamic language and have an array of callbacks as "methods" and gin up a way to call them using templates or macros and pushing 'this' onto the stack before the rest of the parameters. But it would be insane :)
Or Categories in Objective C.
There are conceptual approaches to extending class architectures (not single classes) in C++, but it's not a casual act, and requires planning ahead of time. Sorry.
Sounds like a classic inheritance problem to me. Except I would drop the code in an "Engine Enhancements" directory & include that concept in your architecture.