This question already has answers here:
What is this weird colon-member (" : ") syntax in the constructor?
(14 answers)
Closed 9 years ago.
Please could someone explain to me what this operator does in C++ at a function?
class simplecanny
{
ros::NodeHandle nh_;
ros::NodeHandle n;
ros::Publisher pub ;
image_transport::ImageTransport it_;
image_transport::Subscriber image_sub_; //image subscriber
image_transport::Publisher image_pub_; //image publisher(we subscribe to ardrone image_raw)
std_msgs::String msg;
public:
*** simplecanny()
: it_(nh_) ***
{
image_sub_ = it_.subscribe("/ardrone/image_raw", 1, &simplecanny::imageCb, this);
image_pub_= it_.advertise("/arcv/Image",1);
}
~simplecanny()
{
cv::destroyWindow(WINDOW);
}
...
At the simplecanny() : it_(nh_) constructor, Im not familiar with the : it_(nh_) part. What does it do? Is that a case of operator overloading?
Thanks in advance!
This is called the constructor initializer list. It gives the parameters to be passed to the constructors of the base classes and members of the class.
In your example, it is passing nh_ to the constructor of it_.
Any base class or member that does not appear in this list is constructed using their respective default constructors.
Call the superclass constructor in the subclass' initialization list.
The single colon (:) is no operator but a part of the language, indication the start of an initialization list. The initialization list can be used only in constructors and is used to initialize the object's member variables and superclass subobjects. In your case, the member variable it_ is initialized with nh_. You might want to look up initialization lists and constructors in the texbook of your choice.
It is a constructor initialization list. You can read more on the subject at In this specific case, is there a difference between using a member initializer list and assigning values in a constructor?
It is the member-initialization-list. It permits to pass the correct parameters and chose the good constructor for the members of the class and the constructor of the base classes.
The standard says:
12.6.2 Initializing bases and members [class.base.init]
In the definition of a constructor for a class, initializers for direct and virtual base subobjects and non-static data members can be specified by a ctor-initializer, which has the form
ctor-initializer:
: mem-initializer-list
Any members or base class not specified in the member-initialization-list will use its default constructor.
In you case, you are passing nh_ to the constructor of image_transport::ImageTransport to initialize it_.
The column represents a start of an initialization list. It is used for setting up the variables of objects. Its another important and useful feature is invocation of desired constructor of based class which this class derives. The detailed answer and reason why it is introduced to C++ can be found at Constructor initialization lists and invocation of desired constructor of based class
Related
This question already has answers here:
Initialization Order of Class Data Members
(2 answers)
Closed 4 years ago.
I have three class. First one is the 'Game', which is dependent to the other two. My second class is 'Window', which is a dependence for the third class 'VKBase'. Those last two classes have no parameters in their constructor functions. Game contains the others as object members, and Window have to get initialised before VKBase.
class Game
{
Boolean bit = true;
Window window;
VKBase VkBase;
public:
Game();
~Game();
void _Set();
void Loop();
void Exit();
};
Because that these two class not have parameters in their constructor functions, i can't initialise them in the constructor function of the Game. So they will get initialised whenever i create an object from the class Game.
But the question is, since initialisation order is important, which one will get initialised first? The window or the VkBase?
Initialization order is always left-to-right: first class bases, left-to-right, then member variables in declaration order. So the first one to be initialized in your class is bit, and then follows window.
In which order object class members [...] are initialized?
In the order in which they were declared. In your example, bit is initialized first, window second, VkBase third. Whether these data members have a default constructor or one depending on parameters doesn't matter here.
Because that these two class not have parameters in their constructor functions, i can't initialise them in the constructor function of the Game
You kind got that wrong, you do in fact initialize the instances by calling the default constructor. Note that for any class that has a default constructor,
ClassWithDefaultCtor instance;
does call this default constructor when this variable is instantiated (might be when an enclosing class is constructed, if the above declaration is a class data member). This syntax is called default initialization, and this is exactly what happens in your class. Note that you can change the above to
ClassWithDefaultCtor instance{};
which might make it clearer that the object is properly initialized.
This question already has answers here:
When do we need to have a default constructor?
(7 answers)
Closed 8 years ago.
I have the following classes:
class ArithmeticExpression
{
public:
ArithmeticExpression(std::string expr);
}
class Command
{
public:
Command(){};
//this is a virtual class
}
class CommandAssign : public Command
{
private:
ArithmeticExpression expr;
public:
CommandAssign();
CommandAssign(ArithmeticExpression);
}
Now when I try to write the constructor for the CommandAssign class as in:
CommandAssign::CommandAssign(ArithmeticExpression expr)
:Command()
{
this -> expr = ArithmeticExpression(expr.getExpr());
}
I get the error:
no matching function for call to ‘ArithmeticExpression::ArithmeticExpression()’
:Command()
Apparently I can fix that by adding an empty constructor in ArithmeticExpression class that does not do anything. What is it so special about this empty constructor that makes it work? I do not explicitly call anywhere. Do you always need to define an empty constructor in C++?
I wanted to emphasize that although from the title it seems that my question is similar to the one some users suggested as being a duplicate of, the answer I was looking for is NOT there. I was simply trying to understand what happens when a constructor is called and how to avoid defining a useless default constructor, which I knew already is not automatically defined by the compiler in the case where I define one with parameters.
A default constructor will only be automatically generated by the compiler if no other constructors are defined.
EDIT:
The default constructor is needed for object initialization.
All members are initialised before the constructor body begins. If one doesn't have an entry in the initialiser list, then it will be default-initialised; but this is only possible (for a class type) if it has a default constructor.
expr is not initialised in the initialiser list, and doesn't have a default constructor (since declaring any constructor prevents one from being implicitly generated), so it can't be initialised - hence the error.
You should initialise it in the list, rather than reassigning it in the constructor body:
CommandAssign::CommandAssign(ArithmeticExpression expr) :
expr(expr.getExpr())
{}
Note that there's no need to explicitly default-construct the Command sub-object. This also requires the constructor of ArithmeticExpression to be public: it's private in your example code.
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.
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.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is this weird colon-member syntax in the constructor?
I'm trying to understand what this kind of code means
Say I have this
class OptionStudent: public Student // derived class from Student class
{
public:
explicit OptionStudent(const std::string id = "12345678",
const std::string first = "someone")
: Student(id, first)
{
count_++;
}
}
What is that colon after the "someone"): <-- part called or mean for this constructor?
I know the constructor may be a little incorrect but I don't know what this is called. I just copied my notes from what the instructor was writing on the board and didn't understand it.
Something to do with the class or object remembering something?
It is the member initialization list. In this case, it calls the base class's constructor with id and first as arguments. It could also provide initial values for non-static data members of your class (if you had any).
Note that the semicolon after Student(id, first); is a syntax error and needs to be removed.
It is called an "initialization list". See following article "Understanding Initialization Lists in C++".
The basic idea is that when you enter the code of constructor after { you should have all members initialized to values passed as arguments or default.
Using initialization lists you can also pass arguments directly to base class too! This is what is happening in example you are describing:
first, both id and first are set to some values using default parameter value.
second, these values are used to initialize base Student class.
Of course one can pass different values as OptionStudent arguments and these values would be used to initialize Student.