Making default constructor private in Qt custom object - c++

I'm reading this Qt doc page about custom types, and it states the following:
The default constructor, copy constructor and destructor are all required, and must be public, if the type is to be integrated into the meta-object system.
Suppose I have an object that needs to be built with some required parameters, because it has no sense to be built using the default constructor, for example:
struct IntPair
{
IntPair(int first, int second);
~IntPair();
};
To make it available in the Qt Meta Object system, as the doc states, it requires the default constructor. But practically, it has no sense to give the opportunity to build an IntPair object without a pair of integer numbers (sorry for the ugly example).
Is there a way to achieve this without implementing the default constructor? I'm thinking about a sort of friendship between my object and the Qt Meta Object system...
Basically, I cannot understand why the default constructor is needed.

There are two parts to the question:
Achieving a custom Meta Object without implementing a default ctor.
Understanding why a default ctor is required by Qt in this case.
Other respondents have addressed (2) already.
I wish to address (1).
I wrote a class, and I intend for users of this class to call a ctor I wrote which requires several arguments. However, because of the Qt-related requirements, I am forced to add a zero-argument constructor.
It would make me happy to at least make the zero-arg ctor private, so that I could enforce that all user code EXCEPT moc-generated "magic" code will be barred from using that ctor.
Hello, happiness! It is possible.
You can indeed use friendship to make the default ctor private and still use Qt Metatype.
It looks something like this:
class MyClass {
Q_GADGET
Q_PROPERTY(QString text READ text)
public:
MyClass(QString text, bool sometruth, int someint);
QString text() const { return text_; }
private:
// Works in my project using Qt 5.12. (see hints below if it fails for you)
friend struct QtMetaTypePrivate::QMetaTypeFunctionHelper<MyClass, true>;
// Prefer the ctor that takes arguments. This ctor only exists to satisfy Qt.
MyClass();
QString text_;
};
There are two ways you can solve the problem of figuring out WHAT to befriend.
You can mark the ctor private, try to recompile, and scrutinize the compiler error to figure out what other type is trying to access the ctor of your class.
Or, you can put an assert(false); in the body of your ctor, create a binary with debug symbols (including Qt debug symbols), then look at the stack in the debugger when the assertion fails. The stack will show the Qt-internal member-function or free function that called into your ctor. Friend whatever that caller is.
This last method (using the debugger) is what worked for me. (I wasn't fluent enough in compiler-ese to discern which type from the output of the gigantic compiler error was what I needed to add as my friend.)

It has to do with QVariant's (templated) implementation.
Look at qvariant.h in the QT5.5 source code tree, and you'll find this:
T t;
if (v.convert(vid, &t))
return t;
return T();
And also:
old->~T();
new (old) T(t); //call the copy constructor
Hence the need for a public constructor/desctructor, and copy-constructor.
The advantage of all of this is being able to use your custom type in signals/slots (and other meta-object magic), but there are drawbacks like in your situation. It's just a trade-off that you have to live with.
As a workaround, you could have some sort of "init()" method that actually initializes the object after it's constructed. Not as safe/elegant, but it works.

As to why, there's a design reason behind it. It involves a "Identity vs Value" discussion that I think is too long to paste here.
As to how, #AlexanderVX commented on using default values in arguments.

Custom data type should have public default constructors because many parts of the Qt framework will call it to avoid returning null pointers. E.g. QVariant and containers accessors (e.g. QHash::value()).
In your case IntPair() : IntPair(0,0) { } should be nice, isn't it ?
In many cases it is convenient to hold data in objects impementing Qt's implicit sharing pattern (see http://doc.qt.io/qt-5/implicit-sharing.html), in which case the default constructor may easily initialize with QSharedDataPointer(0) and every accessor return a default value when pointer is null (e.g. 0 for an int, QString() for a QString, etc.), guess what: every accessor will be able to provide a default value by calling the public default constructor of the data type because it is required to have one :-).

Related

What is the advantage of returning an object in a static function instead of building it?

Consider the following documentation of the Qt Framework as an example, even if my question is not Qt specific:
https://doc.qt.io/qt-5/qversionnumber.html
You can find the static public member function:
QVersionNumber fromString(const QString &string, int *suffixIndex = nullptr)
instead of:
QVersionNumber(const QString &string, int *suffixIndex = nullptr)
in the constructors list.
I've seen this choice made in many libraries API and I cannot understand what is the advantage and why that constructor is missing.
This is actually a great question.
The reasons will vary from scenario to scenario, but involve such concerns as:
How readable is the constructor?
Am I creating artificial objects or unnecessarily duplicating conditionals in order to write the constructor in terms of an initialiser list?
Could my constructor have an ambiguity with a constructor meant to perform a different kind of construction?
Is it obvious what my constructor is doing without having to spell out a name in code?
All of the above will involve some degree of subjectivity.
hypothetical example, guessing at the internals of a QVersionNumber,
How would you write this in terms on an initialisation list?
QVersionNumber
QVersionNumber::fromString(const QString &string, int *suffixIndex)
{
std::optional<QVersionNumber> result;
auto first = string.begin();
auto last = string.end();
auto opt_major = maybe_extract_decimal(first, last); // modifies first
if (not opt_major.has_value())
result.emplace();
else
{
auto opt_minor = maybe_extract_decimal(first, last); // modifies first
if (not opt_major.has_value())
result.emplace(*opt_major);
else
result.emplace(*opt_minor);
}
if (suffixIndex)
*suffixIndex = int(std::difference(string.begin(), first);
return *std::move(result);
}
It's certainly possible, deferring to a private constructor which takes a specialised function object. But the author of the library may have taken the view that this is too cryptic or difficult to maintain.
Static creating methods are convenient because they do not require the redundant objects creation and can be added to the code of the object which they creates.There are many reasons to use creational method insteed constructor. Here are just a few:
The constructor must always be completed with the valid object creation. Using an exception in the constructor is a very bad practice. What can we do if the object creation is impossible, for example due to incorrect arguments or incorrect initialization order? In the case of a creational method, you can simply return nullptr or some "wrong" object type.
If we want to customize the object creation without changing its code. For example, we want to build an object and configure it, or we don't have constructor for available arguments. The wrapper function allows you to solve the problem without touching the class code. This applies to the given example, as you can see, fromString parse string argument before constructor call.
We do not know what kind of object to construct. This is decided at run-time. In general, we can return the base object, and choose necessary class inside the wrapper. This allows you to not change the main code for concrete object selection.
We want to control the creation of all objects to eliminate possible memory leaks. For example, when deinitializing a library, release all resources, even if the user forgot to do it.
I recommend you to familiarize with the design patterns, especially with сreational pattern.

How to model noncopyable in Rational Rhapsody 8.0.1

I want to make a class in my Rhapsody model non-copyable, but
don't have the boost library available (from which I would just derive)
nor can I use the C++11 way of disabling the default generated copy ctor and copy assignment op (because I would need to manipulate the function signature, which AFAIK is not directly possible)
=> so I am doing it the old fascioned way.
What I need from Rhapsody:
In this context, I want to generate only a declaration for copy ctor and copy assignment op - I don't need the implementation.
Is this even possible?
Things that I considered:
I haven't found any helpful property yet.
Mapping only the specification of a member function to a file object won't prevent Rhapsody from generating the empty function body into an implicitly created file object (that I don't need nor want).
I would suggest a stereotype approach:
Create a NonCopyable base class, as, for example, described by #Dennis.
Create a stereotype, you can, for example, name it <<non-copyable>>.
a) Set the stereotype property CPP_CG::Class::AdditionalBaseClasses to NonCopyable (the name of the base class created above).
b) Make the stereotype applicable to classes.
Finally, add the <<non-copyable>> stereotype to all classes that shall be non copyable.
Write a private copy ctor and opertor:
class NonCopy {
// These private versions of the copy constructor
// and operator will signal to the compiler to
// prevent automatic generation.
NonCopy(const NonCopy& other);
const NonCopy& operator=(const NonCopy& other);
public:
// Your public ctors
NonCopy(int a);
}
You can look at the boost version of the non-copyable interface for a more complete example.
This can be done (at least in Rhapsody 8.2.0) using a combination of properties of the constructor. First, set the CG::Operation::Generate property to Specification, then set the CPP_CG::Operation::PostDeclarationModifier to = delete. (Both of these are set at the constructor level). This ensures that no function body is created, and also allows usage of the delete keyword via modification of the function signature.
I have not found a way to write this in code and have Rhapsody interpret it correctly while roundtripping, though.

C++ construct asks for a struct that is not defined in .h

I have to do some changes in a project so I have to change some classes. This code was made by another person and I found a really weird problem doing my task (or at least trying until this wild mushroom appeared )
I have the next ClassA.cpp and I want to remove the m_ElemVar(enumType):
CClassA::CClassA(): m_iIntVariable(0), m_fFloatVar(0.0f), m_ElemVar(enumType1)
{
// more variables initizalized there
otherVariable = value;
...
}
the .h :
#include "CMyElement"
class CClassA
{
public:
CClassA();
virtual ~CClassA();
private:
CMyElement m_ElemVar; // THIS is the var
int m_iIntVariable;
float m_fFloatVar;
...
}
So the thing is that I don't want the m_ElemVar(enumType1) there because I will initialize it in another place, BUT if I remove it, when I build the class or the project it says:
error: no matching function for call to ‘CMyElemnt::CMyElemnt()
candidates are CMyElemnt::CMyElemnt(enumTypeName)
while if I remove the m_fFloarVar for example it doesn't complains.... That confuses me a lot because as you can see in the .h there is nothing declared so I understand that this constructor should not expect anything.
I've clean and build it again, and also searched into google but nothing found so any help would be very appreciated. Thank you so much
Looks like CMyElemnt does not have a parameterless constructor so you have to call one that takes the enum. Maybe you could reassign it later if you cannot change its interface.
The issue you are having is all objects of a class must be constructed in order for the class to be constructed. If you don't construct one of the member explicitly then the compiler will do it for you implicitly using the default constructor. Since CMyElemnt does not have a default constructor you will get an error. The reason not initializing m_fFloatVar works is it is a float and the compiler can default construct a float.
To look at a different way anything you can write as
some_type some_name;
Is default constructable. If you have do include parameters like:
some_type some_name(some_variables)
Then it is not default constructable and you need to initialize it yourself.

Compile time check for consecutive functions call

Suppose we have a class like this:
class OProcess {
...
void Process1();
void Process2(); // call only if Process1 wasn't called
...
}
such that function Process2() can be called only when function Process1() has NOT been called already.
Is there a way to check that Process class is used correctly at compile-time? I.e. compiler must give an error if Process1() CAN BE called before Process2() for some instance of OProcess object.
P.S. I understand that there can be code like this:
if (variable == 1000)
Process1();
Process2();
and compiler can't be sure that Process1() will be called before Process2(). But here compiler can be sure that Process1() CAN be called before Process2() for some values of variable. And I need it to make an error or at least warning.
The short answer is Somewhat.
The long answer is: C++ does not implement Linear Typing, thus uniqueness checks cannot be done at compile-time (fully). Still, reading this description gives us a trick: to implement this in the compiler, language designer forbid aliasing and enforce consumption.
So, if you agree that some runtime checks are allowed, then this can be done by having processes consume the object:
class OProcess {
public:
};
std::unique_ptr<OProcessed1> process1(std::unique_ptr<OProcess> op);
std::unique_ptr<OProcess> process2(std::unique_ptr<OProcess> op);
Where OProcessed1 is a proxy over OProcess presenting a restricted interface that exposes only those operations allowed on OProcess after that Process1 was called.
The runtime part of the checks is that:
void func(std::unique_ptr<OProcess> op) {
process1(std::move(op));
process2(std::move(op));
}
will compile, even though it is undefined behavior to do anything other than destruction/assignment to op after moving from it.
The correct way to do it is either make init private and reduce the risk you mention,
or use dependency injection, as 'init' methods, or any logic at all inside the constructor, are bad practice in terms of clean code
Another trick is to have ProcessBase that defines init and calls it in it's constructor. ProcessBase's constructor is called before the derived constructor, thus making sure that init is called before any logic is made in the derived class.
Edit:
You may want to change the logic to have both methods private and have one method called process3() that will call the other methods in the correct order.
Another option is to use the decorator design pattern and wrap one method in a class and have your decorator call them by order.

C++: Copy constructor: Use getters or access member vars directly?

I have a simple container class with a copy constructor.
Do you recommend using getters and setters, or accessing the member variables directly?
public Container
{
public:
Container() {}
Container(const Container& cont) //option 1
{
SetMyString(cont.GetMyString());
}
//OR
Container(const Container& cont) //option 2
{
m_str1 = cont.m_str1;
}
public string GetMyString() { return m_str1;}
public void SetMyString(string str) { m_str1 = str;}
private:
string m_str1;
}
In the example, all code is inline, but in our real code there is no inline code.
Update (29 Sept 09):
Some of these answers are well written however they seem to get missing the point of this question:
this is simple contrived example to discuss using getters/setters vs variables
initializer lists or private validator functions are not really part of this question. I'm wondering if either design will make the code easier to maintain and expand.
Some ppl are focusing on the string in this example however it is just an example, imagine it is a different object instead.
I'm not concerned about performance. we're not programming on the PDP-11
EDIT: Answering the edited question :)
this is simple contrived example to
discuss using getters/setters vs
variables
If you have a simple collection of variables, that don't need any kind of validation, nor additional processing then you might consider using a POD instead. From Stroustrup's FAQ:
A well-designed class presents a clean
and simple interface to its users,
hiding its representation and saving
its users from having to know about
that representation. If the
representation shouldn't be hidden -
say, because users should be able to
change any data member any way they
like - you can think of that class as
"just a plain old data structure"
In short, this is not JAVA. you shouldn't write plain getters/setters because they are as bad as exposing the variables them selves.
initializer lists or private validator functions are not really
part of this question. I'm wondering
if either design will make the code
easier to maintain and expand.
If you are copying another object's variables, then the source object should be in a valid state. How did the ill formed source object got constructed in the first place?! Shouldn't constructors do the job of validation? aren't the modifying member functions responsible of maintaining the class invariant by validating input? Why would you validate a "valid" object in a copy constructor?
I'm not concerned about performance. we're not programming on the PDP-11
This is about the most elegant style, though in C++ the most elegant code has the best performance characteristics usually.
You should use an initializer list. In your code, m_str1 is default constructed then assigned a new value. Your code could be something like this:
class Container
{
public:
Container() {}
Container(const Container& cont) : m_str1(cont.m_str1)
{ }
string GetMyString() { return m_str1;}
void SetMyString(string str) { m_str1 = str;}
private:
string m_str1;
};
#cbrulak You shouldn't IMO validate cont.m_str1 in the copy constructor. What I do, is to validate things in constructors. Validation in copy constructor means you you are copying an ill formed object in the first place, for example:
Container(const string& str) : m_str1(str)
{
if(!valid(m_str1)) // valid() is a function to check your input
{
// throw an exception!
}
}
You should use an initializer list, and then the question becomes meaningless, as in:
Container(const Container& rhs)
: m_str1(rhs.m_str1)
{}
There's a great section in Matthew Wilson's Imperfect C++ that explains all about Member Initializer Lists, and about how you can use them in combination with const and/or references to make your code safer.
Edit: an example showing validation and const:
class Container
{
public:
Container(const string& str)
: m_str1(validate_string(str))
{}
private:
static const string& validate_string(const string& str)
{
if(str.empty())
{
throw runtime_error("invalid argument");
}
return str;
}
private:
const string m_str1;
};
As it's written right now (with no qualification of the input or output) your getter and setter (accessor and mutator, if you prefer) are accomplishing absolutely nothing, so you might as well just make the string public and be done with it.
If the real code really does qualify the string, then chances are pretty good that what you're dealing with isn't properly a string at all -- instead, it's just something that looks a lot like a string. What you're really doing in this case is abusing the type system, sort of exposing a string, when the real type is only something a bit like a string. You're then providing the setter to try to enforce whatever restrictions the real type has compared to a real string.
When you look at it from that direction, the answer becomes fairly obvious: rather than a string, with a setter to make the string act like some other (more restricted) type, what you should be doing instead is defining an actual class for the type you really want. Having defined that class correctly, you make an instance of it public. If (as seems to be the case here) it's reasonable to assign it a value that starts out as a string, then that class should contain an assignment operator that takes a string as an argument. If (as also seems to be the case here) it's reasonable to convert that type to a string under some circumstances, it can also include cast operator that produces a string as the result.
This gives a real improvement over using a setter and getter in a surrounding class. First and foremost, when you put those in a surrounding class, it's easy for code inside that class to bypass the getter/setter, losing enforcement of whatever the setter was supposed to enforce. Second, it maintains a normal-looking notation. Using a getter and a setter forces you to write code that's just plain ugly and hard to read.
One of the major strengths of a string class in C++ is using operator overloading so you can replace something like:
strcpy(strcat(filename, ".ext"));
with:
filename += ".ext";
to improve readability. But look what happens if that string is part of a class that forces us to go through a getter and setter:
some_object.setfilename(some_object.getfilename()+".ext");
If anything, the C code is actually more readable than this mess. On the other hand, consider what happens if we do the job right, with a public object of a class that defines an operator string and operator=:
some_object.filename += ".ext";
Nice, simple and readable, just like it should be. Better still, if we need to enforce something about the string, we can inspect only that small class, we really only have to look one or two specific, well-known places (operator=, possibly a ctor or two for that class) to know that it's always enforced -- a totally different story from when we're using a setter to try to do the job.
Do you anticipate how the string is returned, eg. white space trimmed, null checked, etc.? Same with SetMyString(), if the answer is yes, you are better off with access methods since you don't have to change your code in zillion places but just modify those getter and setter methods.
Ask yourself what the costs and benefits are.
Cost: higher runtime overhead. Calling virtual functions in ctors is a bad idea, but setters and getters are unlikely to be virtual.
Benefits: if the setter/getter does something complicated, you're not repeating code; if it does something unintuitive, you're not forgetting to do that.
The cost/benefit ratio will differ for different classes. Once you're ascertained that ratio, use your judgment. For immutable classes, of course, you don't have setters, and you don't need getters (as const members and references can be public as no one can change/reseat them).
There's no silver bullet as how to write the copy constructor.
If your class only has members which provide a copy constructor that creates
instances which do not share state (or at least do not appear to do so) using an initializer list is a good way.
Otherwise you'll have to actually think.
struct alpha {
beta* m_beta;
alpha() : m_beta(new beta()) {}
~alpha() { delete m_beta; }
alpha(const alpha& a) {
// need to copy? or do you have a shared state? copy on write?
m_beta = new beta(*a.m_beta);
// wrong
m_beta = a.m_beta;
}
Note that you can get around the potential segfault by using smart_ptr - but you can have a lot of fun debugging the resulting bugs.
Of course it can get even funnier.
Members which are created on demand.
new beta(a.beta) is wrong in case you somehow introduce polymorphism.
... a screw the otherwise - please always think when writing a copy constructor.
Why do you need getters and setters at all?
Simple :) - They preserve invariants - i.e. guarantees your class makes, such as "MyString always has an even number of characters".
If implemented as intended, your object is always in a valid state - so a memberwise copy can very well copy the members directly without fear of breaking any guarantee. There is no advantage of passing already validated state through another round of state validation.
As AraK said, the best would be using an initializer list.
Not so simple (1):
Another reason to use getters/setters is not relying on implementation details. That's a strange idea for a copy CTor, when changing such implementation details you almost always need to adjust CDA anyway.
Not so simple (2):
To prove me wrong, you can construct invariants that are dependent on the instance itself, or another external factor. One (very contrieved) example: "if the number of instances is even, the string length is even, otherwise it's odd." In that case, the copy CTor would have to throw, or adjust the string. In such a case it might help to use setters/getters - but that's not the general cas. You shouldn't derive general rules from oddities.
I prefer using an interface for outer classes to access the data, in case you want to change the way it's retrieved. However, when you're within the scope of the class and want to replicate the internal state of the copied value, I'd go with data members directly.
Not to mention that you'll probably save a few function calls if the getter are not inlined.
If your getters are (inline and) not virtual, there's no pluses nor minuses in using them wrt direct member access -- it just looks goofy to me in terms of style, but, no big deal either way.
If your getters are virtual, then there is overhead... but nevertheless that's exactly when you DO want to call them, just in case they're overridden in a subclass!-)
There is a simple test that works for many design questions, this one included: add side-effects and see what breaks.
Suppose setter not only assigns a value, but also writes audit record, logs a message or raises an event. Do you want this happen for every property when copying object? Probably not - so calling setters in constructor is logically wrong (even if setters are in fact just assignments).
Although I agree with other posters that there are many entry-level C++ "no-no's" in your sample, putting that to the side and answering your question directly:
In practice, I tend to make many but not all of my member fields* public to start with, and then move them to get/set when needed.
Now, I will be the first to say that this is not necessarily a recommended practice, and many practitioners will abhor this and say that every field should have setters/getters.
Maybe. But I find that in practice this isn't always necessary. Granted, it causes pain later when I change a field from public to a getter, and sometimes when I know what usage a class will have, I give it set/get and make the field protected or private from the start.
YMMV
RF
you call fields "variables" - I encourage you to use that term only for local variables within a function/method