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.
Related
This question already has answers here:
Constructor initialization-list evaluation order
(3 answers)
Closed last year.
Can I safely use members to initialize others?
class Class {
public:
Class(X argument) : memberA(argument), memberB(memberA) {}
A memberA;
B memberB;
};
Here we use the argument to the constructor to initialize memberA. We then rely on the fact that this happens before the initialization of memberB and initialize memberB using memberA.
If we assume X, A, and B to be std::string the above example works (tested with gcc), as long as we do not change the order in which the members are declared. But is this actually guaranteed by the standard or am I abusing an implementation detail of the compiler?
Yes, this is safe as per class.base.init#15
The expression-list or braced-init-list of a mem-initializer is in the function parameter scope of the constructor and can use this to refer to the object being initialized.
This Note also has an example with this->i to show that previously initialized class members can be used to initialize other class members inside a mem-initializer. (The this-> is only necessary in this example to disambiguate the member and the constructor parameter, both named i).
Be careful that the member is already initialized before using it, since from class.base.init#13.3
... non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).
This question already has answers here:
Why can't member initializers use parentheses?
(2 answers)
Closed 7 months ago.
I have a line of code inside a class's private member variables:
vector<double> dQdt(3)
When compiling in xcode, this gives an error "expected parameter declarator." I think I provided sufficient info. I don't see anything wrong with this declaration.
You have to initialize the variable in the constructor's initializer list:
class X
{
private:
vector<double> dQdt;
public:
X() : dQdt(3) {}
};
If you read e.g. this member initialization reference you will learn that default member initialization have to be a brace or equals initializer. I.e. you need to either use curly-braces:
std::vector<double> dQdt{ 0.0, 0.0, 0.0 };
or using the equals character:
std::vector<double> dQdt = std::vector<double>(3);
Since this was introduced with the C++11 standard, you need to enable that in your environment.
I got this error while trying to compile my C++ code having an initialized vector.
Change the () to {} worked for me in the initialization part;
Earlier my code looked like this:
vector<vector<int>> minA(11, vector<int>(11, INT_MAX));
I changed my code to replace circular brackets with curly braces and the error disappered.
vector<vector<int>> minA{11, vector<int>(11, INT_MAX)};
The parameter for constructors of data members should be written in the initializer list of your class' constructor. That is, instead of
class Foo {
vector<double> dQdt(3);
};
You should write
class Foo {
public:
Foo() : dQdt(3) {}
private:
vector<double> dQdt;
};
As well as initializing in the initializer list of the constructor, you can initialize with a brace initializer list:
class Foo {
vector<double> dQdt{3};
};
The actual text of the error is because the compiler was expecting you to declare a function, taking an argument of some type, and return the vector<double>. 3 is not a valid declaration of a parameter to a function.
The question is already answered the following however works as well.
( Which might be more useful to assign initial values. For example 24 times the 42. )
const int default_value = 42;
struct foo
{
vector<double> hour{vector<double>(24,default_value)};
};
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.
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.