How to drag/drop both file and text in same window in wxWidgets? - c++

I'm working on a program that needs to open images from both local disk and internet. WxWidgets provides wxFileDropTarget and wxTextDropTarget, but each class can only support one type of data object (wxFileDataObject and wxTextDataObject). I've try to derive class from two base classes, but the compiler says ambiguous conversions from 'CMyDropTarget *' to 'wxDropTarget *'. How can I create a window accept two data type?

As far as I know, the simplest solution is to use a wxDataObjectComposite, to which you Add() both a wxFileDataObject and a wxTextDataObject.
You derive your own class from wxDropTarget, override its pure virtual OnData(), and call its SetDataObject() with the appropriately constructed wxDataObjectComposite in your derived class' constructor.
There's a pretty good example of it all in the docs for wxDataObjectComposite. It gives you an overview of what needs to be done, just keep in mind that there are a few details that I think are not quite right in there:
The call to wxDropTarget::OnData() won't work, as that's a pure virtual (you shouldn't call it at all in my opinion).
You should, however, call GetData() instead, to populate the wxDataObjectComposite with the preferred data format (or another one that is available), and test its return value.
dataObjects->GetReceivedFormat() should be dataobjComp->GetReceivedFormat().

Related

Double Dreadful Diamond Inheritance issue (alternative solutions allowed)

I ended up in a situation lined out below.
I have one library that is pure CPP without external libraries, and another project that is an SDK to interface with an external library.
"I" in front of the name indicates an abstract class. Arrows indicate inheritance.
I have IDevice which contains HandleInput(data) as a callback, and StartDevice().
Then I have a more specific type of device: ISmartwatch (containing StartTimer), and from that inherits a more specific version SmartwatchV1, which implements HandleInput(data) according to its needs.
That all seemed great until I came to the external SDK part, where the library expects me to use inheritance to interface with it to override some functions. So, I have to inherit from the external library, and from my own CPP library, to override the functions I need. Most of these library overrides suit any device (IExternalLibDevice), but a few are specific to the exact Stopwatch version (ExternallSmartWatchV1).
Then for polymorphism in my SDK, I would like to call and override functions both provided by the library and my own device example: libDevice.StartDevice() and use library calls within this optionally overriden StartDevice. Or stopWatch.StartTimer(), stopwatchV1.libraryOverride().
The object which I need to create is the green one, however, the white SmartWatchV1 is also an object to instantiate in applications without the library. (And obviously I keep in mind any future alternative devices or stopwatch versions.)
I think if I drop any inheritance arrow, I would either lose out on polymorphism (so SDK code will only work for a very specific smartwatch version), or I cannot override functions I need anymore. Composition would be nice, but won't work for overriding functions, or is there an option I don't know about?
And so, I ended up here. I am encountering quite some annoying errors implementing this, since double diamond is usually solved with virtual inheritance (nice page about double diamond: https://isocpp.org/wiki/faq/multiple-inheritance#mi-diamond). However, when applied here (see the v's that indicate "virtual" in the image), I have one inheritance that should both be virtual and not be virtual. Additionally, virtual inheritance makes constructors really annoying in my generic CPP library. Even without virtual (which as far as I'm aware would cause some duplication of classes in memory and a lot of ambiguity to solve), I have some constructor errors ("no suitable default constructor" for a class that must not have a default constructor, etc) issues.
I have been battling to solve this for a long time, and I hope someone more experienced can make a suggestion that provides a better solution for my code structure or issue.
In the end, I solved it by using composition:
Add an IDevice pointer to IExternalLibDevice that is set in the constructor.
In IExternalLibSmartwatch: add an ISmartwatch pointer to the constructor and pass it to its parent constructor. Also, add a function that retrieves the IDevice pointer as an ISmartwatch.
In ExternalSmartwatchV1: also add a SmartwatchV1 to the constructor and pass it to its parent constructor, and create a function that retrieves the IDevice pointer as a SmartwatchV1.
The IDevice pointer holds the reference to the cppLibDevice, and can now be cast to any of the subclasses it belongs to. Downside: I cannot override the cpp lib classes, but it was not a hard requirement for my code, since I created alternative functions in the ExternalLib classes that can optionally call the cppLibDevice functions, or completely replace them.

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.

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

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.

Is there any way to avoid declaring virtual methods when storing (children) pointers?

I have run into an annoying problem lately, and I am not satisfied with my own workaround: I have a program that maintains a vector of pointers to a base class, and I am storing there all kind of children object-pointers. Now, each child class has methods of their own, and the main program may or not may call these methods, depending on the type of object (note though that they all heavily use common methods of the base class, so this justify inheritance).
I have found useful to have an "object identifier" to check the class type (and then either call the method or not), which is already not very beautiful, but this is not the main inconvenience. The main inconvenience is that, if I want to actually be able to call a derived class method using the base class pointer (or even just store the pointer in the pointer array), then one need to declare the derived methods as virtual in the base class.
Make sense from the C++ coding point of view.. but this is not practical in my case (from the development point of view), because I am planning to create many different children classes in different files, perhaps made by different people, and I don't want to tweak/maintain the base class each time, to add virtual methods!
How to do this? Essentially, what I am asking (I guess) is how to implement something like Objective-C NSArrays - if you send a message to an object that does not implement the method, well, nothing happens.
regards
Instead of this:
// variant A: declare everything in the base class
void DoStuff_A(Base* b) {
if (b->TypeId() == DERIVED_1)
b->DoDerived1Stuff();
else if if (b->TypeId() == DERIVED_2)
b->DoDerived12Stuff();
}
or this:
// variant B: declare nothing in the base class
void DoStuff_B(Base* b) {
if (b->TypeId() == DERIVED_1)
(dynamic_cast<Derived1*>(b))->DoDerived1Stuff();
else if if (b->TypeId() == DERIVED_2)
(dynamic_cast<Derived2*>(b))->DoDerived12Stuff();
}
do this:
// variant C: declare the right thing in the base class
b->DoStuff();
Note there's a single virtual function in the base per stuff that has to be done.
If you find yourself in a situation where you are more comfortable with variants A or B then with variant C, stop and rethink your design. You are coupling components too tightly and in the end it will backfire.
I am planning to create many different children classes in different
files, perhaps made by different people, and I don't want to
tweak/maintain the base class each time, to add virtual methods!
You are OK with tweaking DoStuff each time a derived class is added, but tweaking Base is a no-no. May I ask why?
If your design does not fit in either A, B or C pattern, show what you have, for clairvoyance is a rare feat these days.
You can do what you describe in C++, but not using functions. It is, by the way, kind of horrible but I suppose there might be cases in which it's a legitimate approach.
First way of doing this:
Define a function with a signature something like boost::variant parseMessage(std::string, std::vector<boost::variant>); and perhaps a string of convenience functions with common signatures on the base class and include a message lookup table on the base class which takes functors. In each class constructor add its messages to the message table and the parseMessage function then parcels off each message to the right function on the class.
It's ugly and slow but it should work.
Second way of doing this:
Define the virtual functions further down the hierarchy so if you want to add int foo(bar*); you first add a class that defines it as virtual and then ensure every class that wants to define int foo(bar*); inherit from it. You can then use dynamic_cast to ensure that the pointer you are looking at inherits from this class before trying to call int foo(bar*);. Possible these interface adding classes could be pure virtual so they can be mixed in to various points using multiple inheritance, but that may have its own problems.
This is less flexible than the first way and requires the classes that implement a function to be linked to each other. Oh, and it's still ugly.
But mostly I suggest you try and write C++ code like C++ code not Objective-C code.
This can be solved by adding some sort of introspection capabilities and meta object system. This talk Metadata and reflection in C++ — Jeff Tucker demonstrates how to do this using c++'s template meta programming.
If you don't want to go to the trouble of implementing one yourself, then it would be easier to use an existing one such as Qt's meta object system. Note that this solution does not work with multiple inheritance due to limitations in the meta object compiler: QObject Multiple Inheritance.
With that installed, you can query for the presence of methods and call them. This is quite tedious to do by hand, so the easiest way to call such a methods is using the signal and slot mechanism.
There is also GObject which is quite simmilar and there are others.
If you are planning to create many different children classes in different files, perhaps made by different people, and also I would guess you don't want to change your main code for every child class. Then I think what you need to do in your base class is to define several (not to many) virtual functions (with empty implementation) BUT those functions should be used to mark a time in the logic where they are called like "AfterInseart" or "BeforeSorting", Etc.
Usually there are not to many places in the logic you wish a derived classes to perform there own logic.

Is there a way to determine at runtime if an object can do a method in C++?

In Perl, there is a UNIVERSAL::can method you can call on any class or object to determine if it's able to do something:
sub FooBar::foo {}
print "Yup!\n" if FooBar->can('foo'); #prints "Yup!"
Say I have a base class pointer in C++ that can be any of a number of different derived classes, is there an easy way to accomplish something similar to this? I don't want to have to touch anything in the other derived classes, I can only change the area in the base class that calls the function, and the one derived class that supports it.
EDIT: Wait, this is obvious now (nevermind the question), I could just implement it in the base that returns a number representing UNIMPLEMENTED, then check that the return is not this when you call it. I'm not sure why I was thinking of things in such a complicated manner.
I was also thinking I would derive my class from another one that implemented foo then see if a dynamic cast to this class worked or not.
If you have a pointer or reference to a base class, you can use dynamic_cast to see which derived class it is (and therefore which derived class's methods it supports).
If you can add methods to the base class, you can add a virtual bool can_foo() {return false;} and override it in the subclass that has foo to return true.
C++ does not have built in run-time reflection. You are perfectly free to build your own reflection implementation into your class hierarchy. This usually involves a static map that gets populated with a list of names and functions. You have to manually register each function you want available, and have consistency as to the calling convention and function signature.
I believe the most-correct way would be to use the typeid<> operator and get a reference to the type_info object, and then you could compare that (== operator) to the desired type_info for the data types you wish to care about.
This doesn't give you method-level inspection, and does require that you've built with RTTI enabled (I believe that using typeid<> on an object that was built without RTTI results with "undefined" behavior), but there you are.
MSDN has an online reference to get you started : http://msdn.microsoft.com/en-us/library/b2ay8610%28VS.80%29.aspx