QT : operator after class declaration [duplicate] - c++

This question already has answers here:
What is this weird colon-member (" : ") syntax in the constructor?
(14 answers)
Closed 1 year ago.
Recently I started working on a QT project, but there are more syntax rules than regular C++.
While declaring class and its constructor, in header file, we simply write
class MyObj : public QObject {
Q_OBJECT
public:
explicit MyObj(QObject* parent = nullptr, <params>, ...)
.
.
<some more declarations>
private:
.
.
<some more declarations>
};
In .cpp file, we can define this constructor as
MyObj::MyObj(QObject* parent, <params>) :
QObject(parent),
...
<some more parameter like arguments, that is what I am exactly asking>
{
<regular initializations>
}
I am asking about the parameter like arguments after the : operator in the first line of declaring an initializing the class.
What are they, why QT needs these?
Note: In QT project examples, you can simply find the "Command Line Writer Async" example. In that project, a proper usage of this fact exists. I am using QT 5.15.

That's not an operator. That's a standard c++ feature called member initializer list.
For example
class Test
{
private:
int test_val;
some_type some_test;
public:
Test() :
test_val(7),
some_test()
{}
.
.
//whatever
}
In this example, when an instance of Test is constructed, the members are constructed(or initialized) as shown in the code. test_val is initialized with 7, and some_test is constructed via the call of the default constructor of some_type.
If you written the code above as follows.
class Test
{
private:
int test_val;
some_type some_test;
public:
Test()
{
test_val=7;
some_test=some_type(args...);
}
}
This is equivalent to.
class Test
{
private:
int test_val;
some_type some_test;
public:
Test() :
test_val(),
some_test()
{
test_val=7;
some_test=some_type(args...);
}
}
Which means that every member is constructed(or initialized) by-default, and then is copy-constructed as requested in the body of Test::Test().
The mere purpose for member initialization list is to specify how the members should be initalized
Member initializer list is the place where non-default initialization of these objects can be specified. For bases and non-static data members that cannot be default-initialized, such as members of reference and const-qualified types, member initializers must be specified.

Related

Explanation of C++ class constructor syntax? [duplicate]

This question already has answers here:
What is this weird colon-member (" : ") syntax in the constructor?
(14 answers)
Closed 5 years ago.
Reading through The C++ Programming Language, 4th Edition, there's a class defined like so
class Vector
{
private:
int sz;
double *a;
public:
Vector(int s) :elem{new double[s]}, sz{s} {}
}
I'm a bit confused on how this constructor syntax works. I believe Vector(int s) is creating a constructor function that takes one parameter s, and that it initializes elem and sz. But why is there a :? I thought functions bodies were surrounded by {}? And so what do the empty braces {} at the end serve?
: is called an initialiser list, which is used to quickly and concisely set values for the member variables when the constructor is called.
{} is the constructor's method body. Since the constructor is similar to a method, there has to be a body present for the code to compile. Since there is no need for any code in there, an empty body is used so the function does nothing.
This is initialization with Initializer List.
: is used to "initialize" the members of a class (this method is also called
member initialization list)
there is a major difference between using : and function body {}
initiallizer list : initialize the members of class, whereas ,constructor body {} assigns the value to the members of the class.
the difference may not seem very big but it is actually the only way to initialize the const data type and reference data type members (which can only be initialized during declaration )
So when you do this
class Test
{
const int i; const string str;
public:
Test(int x, string y):i{x},str{y};
}
This would work, but if you try to assign values to const int i and const string str by writing their code in the body of constructor, it would lead to a result
And so what do the empty braces {} at the end serve?
nothing it is just compulsory to put those braces (even if it is empty)
They can basically serve as a function when you create an object of the class inside the main function and pass it the required arguments.

Placing class constructor [duplicate]

This question already has answers here:
Why does decltype not see the member declaration? [duplicate]
(3 answers)
Closed 5 years ago.
Why this code is incorrect?
class Method
{
public:
Method(decltype(info2) info1);
virtual ~Method(){}
protected:
QSharedPointer<info> info2;
};
But this code is correct:
class Method
{
public:
virtual ~Method(){}
protected:
QSharedPointer<info> info2;
public:
Method(decltype(info2) info1);
};
why place of class constructor is important?
I thought that place of definition class constructor isnt important.
I believe this part of the standard is relevant [basic.scope.class]/1.1:
The potential scope of a name declared in a class consists not only of the declarative region following the
name’s point of declaration, but also of all function bodies, default arguments,
exception-specification
s,
and
brace-or-equal-initializers
of non-static data members in that class (including such things in nested
classes).
Note that it only mentions default arguments. So this works since the decltype is referred in a default argument:
Method(QSharedPointer<int> info1 = decltype(info2)())
And this also works since it's inside a body:
Method(<...>)
{
decltype(info2) info3;
}
However your example does not work because such a placement of a decltype is not covered by the paragraph I quoted, thus the name info2 is considered out of scope.
Place of QSharedPointer info2;
is important.
'info2' should be defined before using it into decltype (http://en.cppreference.com/w/cpp/language/decltype).
Next would not work either:
void f() {
d();
}
void d() {
}

does not have field named [duplicate]

This question already has answers here:
How can I initialize base class member variables in derived class constructor?
(7 answers)
Closed 4 years ago.
I have a mistake I cannot understand when initializing member data in an inherited class with two different methods I thought they should be theoretically identical.
class gSolObject
{
public:
gSolObject();
virtual ~gSolObject(){}
bool isCollisionObject;
};
class gPlanetObject : public gSolObject
{
public:
gPlanetObject();
~gPlanetObject(){};
};
gSolObject::gSolObject():isCollisionObject(1)
{
}
gPlanetObject::gPlanetObject():gSolObject(),isCollisionObject(0)
{
}
I get an error class 'gPlanetObject' does not have any field named 'isCollisionObject'.
However when I put the initialization right into the constructor's brackts {..} instead:
gPlanetObject::gPlanetObject():gSolObject()
{
isCollisionObject=0;
}
It compiles fine. Why would that be?
EDIT: This also does not work
gPlanetObject::gPlanetObject():gSolObject(),gSolObject::isCollisionObject(0)
It writes 'expected class-name before '(' token'
You can't initialize member variables declared in base classes, because the base class constructor has already initialized them. All base constructors execute before member constructors.
You can reassign it. Or you can call a base class constructor that takes an argument and initializes its members with that value.
Edited : You can't call a method of a uninitialized object (here gSolObject) and that's why it works when you execute isCollisionObject(0) in the constructor. Furthermore, if you always set it to 0, then you should use default value in the gSolObject constructor.

Initialization of Members in constructor [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ initialization lists
class Base
{
public:
int m_nValue;
Base(int nValue=0)
: m_nValue(nValue)
{
}
};
In this code, is the constructor initializing m_nvalue member variable?
I am not sure of this syntax:
Base(int nValue=0) : m_nValue(nValue) {}
We normally write it as:
Base(int nValue) { m_nValue = nValue;}
Can some one explain the above syntax of C++?
This syntax:
Base(int nValue=0)
: m_nValue(nValue)
is called the member initializer. It will initialize m_nValue with given nValue. This syntax is usually preferred in C++ since it is executed before the body of the constructor.
It's called member initializer list.
The member initializer list consists of a comma-separated list of initializers preceded by a colon. It’s placed after the closing
parenthesis of the argument list and before the opening bracket of the function body
Conceptually, these initializations
take place when the object is created and before any code within the brackets is executed.
Note:
You can’t use the member initializer list syntax with class methods other than constructors.
The way of initializing a variable in your code is called as member initializer list.
Generally we use such list to initialize const member variable (normal - non const also) we because at the time of construction we can give some value to const variable.
Second type of Initialization is basically a normal Parametrised constructor. That is used when you are having a object and at the time of creation of object you want to initialize the member variable.

C++: Initializing something before the bracket [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What does a colon following a C++ constructor name do?
Class construction with initial values
I saw code that looked like this:
class Demo
{
Joystick joystick;
public:
Demo(void):
joystick(1) // The first USB port
{
/* snip */
}
};
Joystick is being initialized before the bracket in the constructor. What does it mean when you do that? What is this called? I'm assuming it differs in some way then initializing joystick inside the bracket -- in what ways does it differ?
It is called an initializer list, and it does differ from initializing inside the body of the constructor.
You can call the constructors of every data member in the class in the initializer list. Also you can call a custom parent class(s) constructor within it, if you didn't, every data member or parent class you don't initialize with the initializer list will be initialized with its default constructor, if it doesn't have, you will see a compiler error.
This is an extended example:
class Parent
{
bool b;
public:
Parent(bool B): b(B)
{
}
};
class Child: public Parent
{
int i;
double d;
public:
Child(int I, double D, bool B): i(I), d(D), Parent(B)
{
}
};
For the order they are called, see this question and this question.
In fact explaining it is an entire article as it's a basic and important thing in classes, just try Googling it and reading some results.