Question regarding inheritance in wxWidgets - c++

Currently I'm attempting to write my own wxObject, and I would like for the class to be based off of the wxTextCtrl class.
Currently this is what I have:
class CommandTextCtrl : public wxTextCtrl {
public:
void OnKey(wxKeyEvent& event);
private:
DECLARE_EVENT_TABLE()
};
Then later on I have this line of code, which is doesn't like:
CommandTextCtrl *ctrl = new CommandTextCtrl(panel, wxID_ANY, *placeholder, *origin, *size);
...and when I attempt to compile the program I receive this error:
error: no matching function for call to ‘CommandTextCtrl::CommandTextCtrl(wxPanel*&, <anonymous enum>, const wxString&, const wxPoint&, const wxSize&)’
It seems that it doesn't inherit the constructor method with wxTextCtrl. Does anyone happen to know why it doesn't inherit the constructor?
Thanks in advance for any help!

C++ does not inherit constructors (you may be thinking of Python, which does;-). A class w/o explicitly declared ctors, like your CommandTextCtrl, in C++, only has default and copy ctors supplied implicitly by C++ rules.
So, you need to explicitly define a ctor with your desired signature, which basically "bounces back" to the base class's -- with the CommandTextCtrl(...): wxTextCtrl(...) {} kind of syntax, of course.

Related

How to make Qt Signal emit by value without compile errors instead of reference?

I read that the signal/slot concept in qt should always pass arguments by value instead of reference to ensure that signals/slots work flawlessly between threads.
I now have a piece of code that will only compile when the argument to a signal is emitted by reference, not value:
#include <QObject>
class mythirdclass {
public:
mythirdclass();
};
class mysecondclass : public QObject, public mythirdclass {
public:
mysecondclass(mythirdclass third);
};
class myclass : public QObject {
Q_OBJECT
public:
myclass();
signals:
// not working
void messageReceived(mysecondclass mymessage);
// working
// void messageReceived(mysecondclass &mymessage);
};
myclass::myclass()
{
mythirdclass third;
mysecondclass msg(third);
emit messageReceived(msg);
}
mysecondclass::mysecondclass(mythirdclass third)
{
// DO stuff
}
mythirdclass::mythirdclass()
{
}
The compiler error is:
..\example\main.cpp: In constructor 'myclass::myclass()':
..\example\main.cpp:28:20: error: use of deleted function 'mysecondclass::mysecondclass(const mysecondclass&)'
emit signal(second);
^
..\example\main.cpp:8:7: note: 'mysecondclass::mysecondclass(const mysecondclass&)' is implicitly deleted because the default definition would be ill-formed:
class mysecondclass : QObject, public mythirdclass {
^
Based on the errors I thought abour writing a copy constructor for mysecondclass, however after some attempts I gave up for now, because I didn't get it right.
So my questions are:
why is the compiling failing in the first place?
if it fails because of a missing copy constructor, why is the compiler not able to define one implicitly?
how would the working copy constructor in my case look like?
Thanks in advance.
Why is the compiling failing in the first place?
Because passing by value implies copying, and if the copy-constructor is deleted, then it simply can't pass by value and your function cannot be compiled with this signature, while it can receive its argument by reference because it doesn't involve copying.
If it fails because of a missing copy constructor, why is the compiler not able to define one implicitly?
It actually fails because it hasn't been able to define one implicitly. The reason for that is that your class derives from QObject. And that QObject doesn't have a public or protected copy-constructor, by design. So the compiler cannot define one implicitly.
How would the working copy constructor in my case look like?
Given the nature of QObjects, and the design decision that's behind it when it comes to QObjects not being copyable, I would recommend against using signals and slots that take QObjects or class deriving from it by value (or simply any function that does this, and signals/slots are mainly functions deep down), but instead by reference or by pointer.
For you third question, if you do not want to define a default constructor for mysecondclass, your copy constructor would probably look like
mysecondclass(mysecondclass const &other) : mythirdclass() {
/// stuff
}
For your second question, I suppose (not sure) that the default copy constructor try to use the default constructor that has been automatically deleted because you have defined another constructor of mysecondclass from an object of mythirdclass (I would recommend to you to use a const reference for the parameter here to avoid a useless copy)

calling default (implicit) copy constructor from the defined copy constructor

I have read many threads regarding this, but I couldn't find an answer to this
In my Qt application, I am using QSignalSpy to catch a signal. It has a user-defined datatype for one of its parameters. To catch such a parameter, I have to first register that datatype with Qt using QMetaType and using the macro Q_DECLARE_METATYPE. It says
This macro makes the type Type known to QMetaType as long as it provides a public default constructor, a public copy constructor and a public destructor. It is needed to use the type Type as a custom type in QVariant.
The problem: I have a class CustomData with only constructor defined. Now unless I explicitly declare a destructor and a copy constructor, Qt throws an error. I want to use the implicit destructor and copy constructor that C++ gives. For destructor, I used
~CustomData() = default;
which uses the default destructor. But I cannot use a similar statement for the copy constructor. Will using
CustomData( const CustomData& ) {};
invoke the implicit copy constructor?
(I am doing this because I want to retain the behavior of the implicit copy constructor)
Thanks in advance.
The CustomData class is shown below
#include <QMetaType>
#include <QString>
class CustomData : public QObject
{
Q_OBJECT
public:
CustomData(QObject *parent = NULL);
~CustomData() = default; // I added this line
//Will the next line call the implicit copy constructor?
CustomData(const CustomData&) {}; //I added this line
enum CustomMode {mode1, mode2, mode3};
void somePublicMethod();
signals:
void completed(CustomData *data);
private slots:
void customComplete();
private:
CustomMode _mode;
QString _path;
CustomData *_chained;
};
Q_DECLARE_METATYPE(CustomData)
In short - it doesn't matter. Your implementation does not(hopefully) cause any effect.
If you go through the Qt documentation, it says as follows
QObject has neither a copy constructor nor an assignment operator. This is by design. Actually, they are declared, but in a private section with the macro Q_DISABLE_COPY(). In fact, all Qt classes derived from QObject (direct or indirect) use this macro to declare their copy constructor and assignment operator to be private.
Go through this -- Q_DISABLE_COPY().
This dictates that you use pointers to do the work. Look at this thread which discusses on how to copy object in Qt.
Actually the given code compiles without errors on Visual Studio 2013. However if the signature of the signal is changed to void completed(CustomData data); then a similar error occurs. Since you have not specified the compiler, but I assume it is gcc/clang you could get the error because template handling differs a bit. If so, the error is most likely caused by Q_DECLARE_METATYPE(CustomData) since it tries to generate the copy constructor inside. Change it to Q_DECLARE_METATYPE(CustomData*) (because that is what you really need, you are queuing arguments of type CustomData* not CustomData, at least in the given sample) and if you really have no signals that send the CustomData instances by value you should be fine.
Also, if you are passing the object by pointer then you should use Q_DECLARE_METATYPE(CustomData*). But I'd advise passing it through a std::unique_ptr or std::shared_ptr to prevent memory leaks.

When is it permitted to make the default constructor private

I have two classes, one has permitted making the only explicitly declared constructor, the no arguments one, private. I recently added another class but am getting compile-time errors due to having made the no argument constructor private. The only difference is the first had a public static factory method while the latter has a non-static constructor which takes an argument.
Thanks, hope this makes some sense.
Okay, I give you some code:
This doesn't compile:
class GridElem {
public:
GridElem(const char _idata);
~GridElem();
private:
GridElem();
}
This does compile:
class GridElem {
public:
GridElem(const char _idata);
~GridElem();
GridElem();
}
This does compile:
class MyClass {
public:
~MyClass();
private:
MyClass();
Not a complete example, sorry, but I believe this shows where the anomally arises, perhaps from extending cocos2d::Layer?
EDIT
Alright I found the call that is doing this (eclipse couldn't find it :()
in header
GridElem myGrid[15][15];
in cpp file
MyClass::MyClass() : myGrid{0} {}
I only recently changed it from a smaller grid and giving each element explicitly (because it was still just 0 for want of more information), I think this must now expand to parameterless c'tor. I completely forgot that, sorry, but it wasn't 100% obvious mistake.
You can always make the default constructor private (or not have a default constructor at all).
What you can't do is use a private default constructor from outside the class (or its friends).
You haven't provided enough context to know for sure, but I suspect your problem is that something else in your code is trying to default construct a GridElem, so it needs to be public.
The only difference is the first had a public static factory method while the latter has a non-static constructor which takes an argument.
If MyScene has a factory method then that's a member and can call the private default constructor. There's no "anomaly", you've just said that both types can only be default constructed by their own member functions (and friends), but only one of them has a member function to actually do that.
making default constructor private usually means you want all
creation to go through a factory. So use said factory, or make it public

When does a class not contain a constructor?

I'm quite new to C++, but have general knowledge of other languages. Lately I've seen some tutorials about C++, and I have sometimes seen classes that do not have their own constructor, not even className();. This might exist in the other languages as well, but I've never seen it before. I don't think I've seen them in use before either, so my question is: what are they for? And what are they? I tried googling this, but I don't know the name for it.. 'constructorless class' didn't give me much.
Without a constructor, is it possible to instantiate it? Or is it more of a static thing? If I have a class that contains an integer, but has no constructor, could I go int i = myClass.int; or something like that? How do you access a constructorless class?
If you don't explicitly declare a constructor, then the compiler supplies a zero-argument constructor for you.*
So this code:
class Foo {
};
is the same as this code:
class Foo {
public:
Foo() {};
};
* Except in cases where this wouldn't work, e.g. the class contains reference or const members that need to be initialized, or derives from a superclass that doesn't have a default constructor.
If you do not specify a constructor explicitly compiler generates default constructors for you (constructor without arguments and copy constructor). So there is no such thing as constructorless class. You can make your constructor inaccessible to control when and how instances of your class created but that's a different story.
A class without a constructor is a good model for implementing an interface.
Many interfaces consist of methods and no data members, so there is nothing to construct.
class Field_Interface
{
public:
// Every field has a name.
virtual const std::string& get_field_name(void) const = 0;
// Every field must be able to return its value as a string
virtual std::string get_value_as_string(void) const = 0;
};
The above class is know as an abstract class. It is not meant to have any function, but to define an interface.

How to prevent construction of a class's object?

I can't find the answer anywhere. It can be done by using condition and throwing exception but is there any other way to do so?
It isn't clear why you would want a class that cannot be constructed under any circumstances, but you could make all constructors private and provide no implementation for them. This will prevent construction at compile time.
In C++11 you can use delete for all the constructors:
class A
{
public: // or private, doesn't matter.
A()=delete;
A(const A&)=delete;
A(A&&)=delete;
};
Well, this is a bit of an awful hack but quite frankly any C++ application which needs a way to define an unconstructable object is probably already an awful hack!
class la
{
public:
virtual void oh_no_you_dont() = 0;
};
int main()
{
la an_instance;
return 0;
}
And under GCC, I get the following:
test.cpp: In function ‘int main()’:
test.cpp:9: error: cannot declare variable ‘an_instance’ to be of abstract type ‘la’
test.cpp:2: note: because the following virtual functions are pure within ‘la’:
test.cpp:4: note: virtual void la::oh_no_you_dont()
You can make all constructors private. This way it's impossible to create an instance of the class. You can then supply one or more static factory methods for creating the class, and by this make the users use only factory methods.
Do you want your class to prevent from being constructed?
Here is a solution with an old C++ standard e.g. C++03 and older
class A {
private:
A();
A(const A&)
A(A&&);
~A()
};
Here is a solution using the latest C++ standard e.g. C++11, C++14, C++17, C++20
class A
{
A()=delete;
A(const A&)=delete;
A(A&&)=delete;
};
or even
class A final {
~A() = delete;
}
final means that a class cannot be inherited from.
delete for a destructor means that you can not destruct a class
Prohibiting a destructor blocks you from constructing an object also.
Why do we want to prohibit objects from being constructed/destructed?
A very common use case is that a developer wants to create a "static" class in C++.
"static" class in C++ means a class with only static methods.
This pattern is also know as an "util" class.
Instead of defining a class many people advice to use a canonical namespace that contains static functions for this purpose.