Reputation: 947
With respect to the class definition for complex number, I saw two types of definitions:
Definition 1
class Complex
{
private:
double re;
double im;
public:
Complex(float r,float i) {re = r; im = i;}
~Complex() {};
};
Definition 2
class Complex
{
private:
double re;
double im;
public:
Complex(double r,double i): re(r), im(i) {}
~Complex() {};
};
The first definition looks OK to me but I do not quite understand the second definition, how does
Complex(double r,double i): re(r), im(i) {}
work? What does "re( )" mean?
Upvotes: 3
Views: 290
Reputation: 39389
In C++ there is a distinction between assignment and initialization.
a = 5; // assignment
int b = 6; // initialization
int b(6); // also initialization
The first version of your class performs assignment inside the body of the constructor. This is more expensive, because the data members re
and im
are first default-constructed, and then are assigned their values.
In the second version constructor initialization list is used. Here the data members are initialized with the supplied values. This occurs in one step, while default constructor + assignment are two steps. This is more efficient.
Generally, you should prefer initializing your data members in the initialization list to assigning their values inside the body of the constructor. There is a caveat, though. The data member in the initialization list are initialized in the order in which they are declared in the class, not in the order in which they occur in the initialization list. Generally, you want the order of members in the list to match their order of declaration. Otherwise you may end up with very hard to find bugs if the initialization of one data member depends on the value of another.
Upvotes: 1
Reputation: 643
First of all, there should be a semicolon after the entire class definition in C++. Otherwise your code will fair to compile.
Anyway, the
Complex(double r,double i): re(r), im(i) {}
is a constructor for the Complex class that simply places the value of r into re and the value of i into im. That is another way of initializing a class's values.
Note that initialization lists like that can be very useful for initializing member classes within a class. Here's an example:
class MemberClass
{
private:
int mValue;
public:
MemberClass(int value): mValue(value) {}
};
class MemberHolder
{
private:
MemberClass mMember;
public:
MemberHolder(int value): mMember(value) {}
};
Initialization lists are important for using classes without a default constructor within other classes.
Upvotes: 1
Reputation: 400174
It's called an initializer list. In a class's constructor, you can initialize member variables with this syntax. So in this, it's equivalent to putting the statements re = r; im = i;
in the body of the constructor.
In the case of POD variables such as int
, double
, and pointer types, there is no difference between the initializer list syntax and regular assignments in the body. However, for const
variables, references, and objects with non-trivial constructors, there is an important difference:
const
variables and reference variables, they must be initialized in the initializer list. They cannot be initialized by assigning to them in the body.Because of that, it's generally recommended that objects with constructors get initialized in the initializer list to avoid redundant work -- if you let its default constructor run by omitting it from the initializer list and then perform some sort of initialization in the constructor body, you're initializing it twice, which can be wasteful.
For example:
class Example
{
private:
std::string m_string;
public:
Example()
{
// m_string is first initialized by the std::string default constructor,
// then we assign to it with operator=(const char *).
// This is inefficient.
m_string = "test";
}
Example(int dummy)
: m_string("test")
{
// Better: we just call the std::string(const char*) constructor directly
}
};
Upvotes: 4
Reputation: 79893
The second form of the Complex
constructor uses initialization lists, which are a different (and preferred way) of initialization class members.
The re(...)
thing means that member field re
should be constructed with whatever arguments it is passed.
As another example - you can create primitives like double
and int
like this:
double d(5.0d);
int i(5);
Which should explain how the parentheses work in the lists.
Upvotes: 2
Reputation: 16007
That's an initialization list. It sets the value of re
to r
and the value of im
to i
.
Generally you'll see a performance gain by using an initialization list, but it's also important to know when not to use it.
Upvotes: 1