why can't objects be created without a constructor? - c++

why does creation of an object needs a constructor?
Even if I don't define a constructor a default constructor is generated ..but why a constructor necessary?

why can't objects be created without a constructor?
This is more of a discussion on terminology than a real argument about the behavior. As you mention, in some cases there is nothing to be done during construction, so there should be no need for a constructor, right? Well, there is the concept of a trivial-constructor which is a constructor that does not do anything at all. For the sake of the standard document, it is easier to treat everything as having a (possibly trivial) constructor than to have to provide all the cases and exceptions in all places where it currently just states 'constructor'.
Consider that every use of 'constructor' would have to be replaced by 'constructor or nothing if the type does not have any virtual functions or bases and no members that require the generation of a constructor'.
This is the same reason why all virtual functions are called overrider even the first one in the hierarchy that by definition does not override anything. This form of generalization makes the language slightly easier to interpret, although not too many people will claim that section 8.5 on initialization is simple...
Also note that, while all user defined types by definition have a constructor, the constructor is not required for the creation of objects. In particular for objects with trivial-constructor the lifetime starts when the memory for the object is allocated (the standard, knowing that trivial means nothing to be done does not even go through the hop of requiring that the constructor is run in that case.
3.8 [basic.life]/1
The lifetime of an object is a runtime property of the object. An object is said to have non-trivial initialization if it is of a class or aggregate type and it or one of its members is initialized by a constructor other than a trivial default constructor. [ Note: initialization by a trivial copy/move constructor is non-trivial initialization. — end note ] The lifetime of an object of type T begins when:
-- storage with the proper alignment and size for type T is obtained, and
-- if the object has non-trivial initialization, its initialization is complete.
That second bullet used to read (C++03): if T is a class type with a non-trivial constructor (12.1), the constructor call has completed. Which more clearly stated that the constructor need not be executed. But the new wording expresses the intent in basically the same way. Only if the object has non-trivial initialization, the initialization needs to complete. For objects with trivial-constructor (trivial initialization) allocating the storage creates the object. Where does it matter?
struct T { int x; }; // implicitly defined trivial-constructor
T *p = static_cast<T*>(malloc(sizeof *p));
// *p is alive at this point, no need to do
T *q;
{ void *tmp = malloc(sizeof T);
q = new (tmp) T; // call constructor
}

In a way, this is a slightly philosophical question. You can think of a constructor as a subroutine that turns some uninitialized memory into an object. Or you can think of it as a language feature that makes initialization easier to follow, write, and understand. You could even answer the question circularly: why does creation of an object needs a constructor? Because that's what creation of an object is, in a sense. If you don't have a constructor, what you're creating isn't an object.
It may be that a particular constructor does nothing, but that's an implementation detail of that class. The fact that every class has a constructor means that the class encapsulates what initialization is necessary: to use the class safely, you don't need to know whether the constructor does anything. In fact, in the presence of inheritance, vtables, debug-tracking, and other compiler features, you might not even know whether the constructor does anything. (C++ complicates this slightly by calling some classes POD types, but the encapsulation holds as long as you don't need to know that something is of POD type.)
The invocation of a constructor defines the point at which an object is created. In terms of language semantics, when the constructor finishes, the constructed object exists: before that, the object does not exist, and it is an error to use it as if it did. This is why construction order (that is, the order that member object and base class sub-object constructors are called) is so important in C++ and similar languages: if your constructor can throw an exception, it's necessary to destroy exactly those objects that have been constructed.
To end up with a working program, the programmer, anyone who tries to understand the source code, the compiler and linker, the runtime library, and any other compilation tools, all need to have a shared idea of what the program means: the semantics of the program. Agreeing on the lifetime of an object—when the compiler can run extra code to help create it, and when you can safely use it—is actually a big part of this agreement. Constructors and destructors are part of defining this lifetime. Even if they happen to be empty sometimes, they provide a way for us to agree when an object is valid, thus making it easier (possible) to specify and understand the language.

Say you have a simple class :
class Foo
{
int bar;
}
What is the value of bar exactly? Maybe you don't care when your object gets its memory allocated, but the machine running your program needs to give it some value. That's what the constructor is for : initializing class members to some value.

Constructor is necessary to call the constructors on class members, except built-in types see

Parametrized Constructors can take arguments. For example:
class example
{
int p, q;
public:
example();
example(int a, int b); //parameterized constructor
};
example :: example()
{
}
example :: example(int a, int b)
{
p = a;
q = b;
}
When an object is declared in a parameterized constructor, the initial values have to be passed as arguments to the constructor function. The normal way of object declaration may not work. The constructors can be called explicitly or implicitly. The method of calling the constructor implicitly is also called the shorthand method.
example e = example(0, 50); //explicit call
example e(0, 50); //implicit call
This is particularly useful to provide initial values to the object.
Also you will find important stuff on this page :
http://en.wikipedia.org/wiki/Constructor_%28object-oriented_programming%29

Related

Is a constructor a function and is it possible to call a constructor

I came across this where one of the user comment says:
A constructor cannot be called, it is not a function. It is invoked automatically when a new object is created.
My question is that is the above comment true/correct? If yes, then why isn't a constructor considered a function and why can't we call it?
Formally in the C++ Standard it is (along with several others) a special member function so yes it is a function, but it is a special function and not all of the normal rules apply.
There is no syntax to write code that calls a constructor directly or forming a function pointer to it. The Standard specifically says "Constructors do not have names."
The compiler will automatically call a constructor when an object is created. The compiler will also automatically call constructors for subobjects (bases and members) of a class object. "Delegating constructors" are sort-of a degenerate case of initialization of subobjects (In formal algebra, we say that any set is a subset of itself, and say "strict" subset when we mean a subset that is not the entire set).
There are a variety of ways to create an object and some of them look like a function call, but that's actually a cast and results in creation of a new object, on which the constructor is called implicitly by the compiler. There's also placement-new syntax which doesn't do very much besides causing the compiler to implicitly call the constructor -- but even there a brand new object is being created.
One important way in which the compiler's implicit call to a constructor differs from an explicit function call found in user code is that the implicit call occurs within an implicit try/catch scope that will result in destruction of subobjects if an exception occurs. A direct call to the constructor, if one were possible, wouldn't have such extra behavior.
When I was using an "union" of objects where I had to manage the destruction and construction of the members of the union, I was able to call the constructor like this using the "new operator":
new(&variable) NameOfTheClass
#include <iostream>
class A {
public: A() {std::cout << "constructor called for pointer " << this << std::endl;}
};
int main() {
A a;
new(&a) A; //Should call a second time the constructor
}
The quoted comment is incorrect. A constructor is a special member function. And it can be implicitly called by the compiler at the time of object creation.
For example,
struct A
{
};
int main()
{
//----v----->note the absence of parenthesis like when we call a function
A a; //creates object of type A by implicitly calling the default constructor
}
These are some of the special(things to be noted) things about constructors:
They don't have return types.
They are automatically synthesized by the compiler given certain conditions are satisfied.
They are implicitly called by the compiler at the time of object creation.
1- Yes, the constructor is a member function with a specific signature having the same name as for Class.
2- The default constructor is called implicitly when it is not called explicitly. But it can be called explicitly using "super()" in Java and "Base()" in C# in respective child classes.

Is a constructor implicitly declared in the case of a abstract class with no data members? [duplicate]

In the book I'm reading at the moment (C++ Without Fear) it says that if you don't declare a default constructor for a class, the compiler supplies one for you, which "zeroes out each data member". I've experimented with this, and I'm not seeing any zeroing -out behaviour. I also can't find anything that mentions this on Google. Is this just an error or a quirk of a specific compiler?
If you do not define a constructor, the compiler will define a default constructor for you.
Construction
The implementation of this
default constructor is:
default construct the base class (if the base class does not have a default constructor, this is a compilation failure)
default construct each member variable in the order of declaration. (If a member does not have a default constructor, this is a compilation failure).
Note:
The POD data (int,float,pointer, etc.) do not have an explicit constructor but the default action is to do nothing (in the vane of C++ philosophy; we do not want to pay for something unless we explicitly ask for it).
Copy
If no destructor/copy Constructor/Copy Assignment operator is defined the compiler builds one of those for you (so a class always has a destructor/Copy Constructor/Assignment Operator (unless you cheat and explicitly declare one but don't define it)).
The default implementation is:
Destructor:
If user-defined destructor is defined, execute the code provided.
Call the destructor of each member in reverse order of declaration
Call the destructor of the base class.
Copy Constructor:
Call the Base class Copy Constructor.
Call the copy constructor for each member variable in the order of declaration.
Copy Assignment Operator:
Call the base class assignment operator
Call the copy assignment operator of each member variable in the order of declaration.
Return a reference to this.
Note Copy Construction/Assignment operator of POD Data is just copying the data (Hence the shallow copy problem associated with RAW pointers).
Move
If no destructor/copy Constructor/Copy Assignment/Move Constructor/Move Assignment operator is defined the compiler builds the move operators for you one of those for you.
The default implementation is:
Implicitly-declared move constructor
If no user-defined move constructors are provided for a class type (struct, class, or union), and all of the following is true:
Move Constructor:
Call the Base class Copy Constructor.
Call the move constructor for each member variable in the order of declaration.
Move Assignment Operator:
Call the base class assignment operator
Call the move assignment operator of each member variable in the order of declaration.
Return a reference to this.
I think it's worth pointing out that the default constructor will only be created by the compiler if you provide no constructor whatsoever. That means if you only provide one constructor that takes an argument, the compiler will not create the default no-arg constructor for you.
The zeroing-out behavior that your book talks about is probably specific to a particular compiler. I've always assumed that it can vary and that you should explicitly initialize any data members.
Does the compiler automatically generate a default constructor?
Does the implicitly generated default constructor perform zero
initialization?
If you legalistically parse the language of the 2003 standard, then the answers are yes, and no. However, this isn't the whole story because unlike a user-defined default constructor, an implicitly defined default constructor is not always used when creating an object from scratch -- there are two other scenarios: no construction and member-wise value-initialization.
The "no construction" case is really just a technicality because it is functionally no different than calling the trivial default constructor. The other case is more interesting: member-wise value-initialization is invoked by using "()" [as if explicitly invoking a constructor that has no arguments] and it bypasses what is technically referred to as the default constructor. Instead it recursively performs value-initialization on each data member, and for primitive data types, this ultimately resolves to zero-initialization.
So in effect, the compiler provides two different implicitly defined default constructors. One of which does perform zero initialization of primitive member data and the other of which does not. Here are some examples of how you can invoke each type of constructor:
MyClass a; // default-construction or no construction
MyClass b = MyClass(); // member-wise value-initialization
and
new MyClass; // default-construction or no construction
new MyClass(); // member-wise value-initialization
Note: If a user-declared default constructor does exist, then member-wise value-initialization simply calls that and stops.
Here's a somewhat detailed breakdown of what the standard says about this...
If you don't declare a constructor, the compiler implicitly creates a default constructor [12.1-5]
The default constructor does not initialize primitive types [12.1-7]
MyClass() {} // implicitly defined constructor
If you initialize an object with "()", this does not directly invoke the default constructor. Instead, it instigates a long sequence of rules called value-initialization [8.5-7]
The net effect of value initialization is that the implicitly declared default constructor is never called. Instead, a recursive member-wise value initialization is invoked which will ultimately zero-initialize any primitive members and calls the default constructor on any members which have a user-declared constructor [8.5-5]
Value-initialization applies even to primitive types -- they will be zero-initialized. [8.5-5]
int a = int(); // equivalent to int a = 0;
All of this is really moot for most purposes. The writer of a class cannot generally assume that data members will be zeroed out during an implicit initialization sequence -- so any self-managing class should define its own constructor if it has any primitive data members that require initialization.
So when does this matter?
There may be circumstances where generic code wants to force initialization of unknown types. Value-initialization provides a way to do this. Just remember that implicit zero-initialization does not occur if the user has provided a constructor.
By default, data contained by std::vector is value-initialized. This can prevent memory debuggers from identifying logic errors associated with otherwise uninitialized memory buffers.
vector::resize( size_type sz, T c=T() ); // default c is "value-initialized"
Entire arrays of primitives type or "plain-old-data" (POD)-type structures can be zero-initialized by using value-initialization syntax.
new int[100]();
This post has more details about variations between versions of the standard, and it also notes a case where the standard is applied differently in major compilers.
C++ does generate a default constructor but only if you don't provide one of your own. The standard says nothing about zeroing out data members. By default when you first construct any object, they're undefined.
This might be confusing because most of the C++ primitive types DO have default "constructors" that init them to zero (int(), bool(), double(), long(), etc.), but the compiler doesn't call them to init POD members like it does for object members.
It's worth noting that the STL does use these constructors to default-construct the contents of containers that hold primitive types. You can take a look at this question for more details on how things in STL containers get inited.
The default constructor created for a class will not initialize built-in types, but it will call the default constructor on all user-defined members:
class Foo
{
public:
int x;
Foo() : x(1) {}
};
class Bar
{
public:
int y;
Foo f;
Foo *fp;
};
int main()
{
Bar b1;
ASSERT(b1.f.x == 1);
// We know nothing about what b1.y is set to, or what b1.fp is set to.
// The class members' initialization parallels normal stack initialization.
int y;
Foo f;
Foo *fp;
ASSERT(f.x == 1);
// We know nothing about what y is set to, or what fp is set to.
}
The compiler will generate default constructors and destructors if user-created ones are not present. These will NOT modify the state of any data members.
In C++ (and C) the contents of any allocated data is not guaranteed. In debug configurations some platforms will set this to a known value (e.g. 0xFEFEFEFE) to help identify bugs, but this should not be relied upon.
Zero-ing out only occurs for globals. So if your object is declared in the global scope, its members will be zero-ed out:
class Blah
{
public:
int x;
int y;
};
Blah global;
int main(int argc, char **argv) {
Blah local;
cout<<global.x<<endl; // will be 0
cout<<local.x<<endl; // will be random
}
C++ does not guarantee zeroing out memory. Java and C# do (in a manner of speaking).
Some compilers might, but don't depend on that.
In C++11, a default constructor generated by the compiler is marked deleted , if :
the class has a reference field
or a const field without a user-defined default constructor
or a field without a default initializer, with a deleted default constructor
http://en.cppreference.com/w/cpp/language/default_constructor
C++ generates a default constructor. If needed (determined at compile time I believe), it will also generate a default copy constructor and a default assignment constructor. I haven't heard anything about guarantees for zeroing memory though.
The compiler by default will not be generating the default constructor unless the implementation does not require one .
So , basically the constructor has to be a non-trivial constructor.
For constructor to be non-trivial constructor, following are the conditions in which any one can suffice:
1) The class has a virtual member function.
2) Class member sub-objects or base classes have non-trivial constructors.
3) A class has virtual inheritance hierarchy.

Are there any consequences from using *this to initialise a class?

In a small game I'm writing, I have a class Weapon with two constructors, one which takes in some parameters to produce a custom weapon, and one that grabs a default one (the CHAIN_GUN):
Weapon::Weapon (void) {
// Standard weapon
*this = getWeapon(CHAIN_GUN);
return;
}
Question: Are there any negative consequences from using *this and operator= to initialise a class?
Imagine that someone asked you to draw a painting... would you;
first draw your default (1st) (that familiar smilie face you like so much),
then draw what that someone asked for (2nd),
only to draw the same thing one more time, but on the canvas containing your default,
and then burn the 2nd painting?
This post will try to explain why this simile is relevant.
WHY IS IT A BAD IDEA?
I've never seen a default-constructor implemented with the use of the assignment-operator, and honestly it's not something that I'd recommend, nor support during a code review.
The major problem with such code is that we are, by definition, constructing two objects (instead of one) and calling a member-function, meaning that we construct all our members two times, and later having to copy/move initialize all members by calling the assignment operator.
It's unintuitive that upon requesting construction of 1 object, we construct 2 objects, only to later copy the values from the 2nd to the 1st and discard the 2nd.
Conclusion: Don't do it.
( Note: In a case where Weapon has base-classes it will be even worse )
( Note: Another potential danger is that the factory function accidentially uses the default-constructor, resulting in an infinite recursion not caught during compilation, as noted by #Ratchet Freat )
PROPOSED SOLUTION
In your specific case you are far better off using a default-argument in your constructor, as in the below example.
class Weapon {
public:
Weapon(WeaponType w_type = CHAIN_GUN);
...
}
Weapon w1; // w_type = CHAIN_GUN
Weapon w2 (KNOWLEDGE); // the most powerful weapon
( Note: An alternative to the above would be to use a delegating constructor, available in C++11 )
Using the assignment operator to implement a constructor is rarely a good idea. In your case, for example, you could just use a default parameter:
Weapon::Weapon(GunType g = CHAIN_GUN)
: // Initialize members based on g
{
}
In other cases, you might use a delegating constructor (with C++11 or later):
Weapon::Weapon(GunType g)
: // Initialize members based on g
{
}
Weapon::Weapon()
: Weapon(CHAIN_GUN) // Delegate to other constructor
{
}
One thing to keep in mind is that if operator= - or any function it calls - is virtual, the derived-class version won't be invoked. This could result in uninitialised fields and later Undefined Behaviour, but it all depends on your data members.
More generally, your bases and data members are guaranteed to have been initialised if they have constructors or appear in the initialiser list (or with C++11 are assigned to in the class declaration) - so apart from the virtual issue above, operator= will often work without Undefined Behaviour.
If a base or member has been initialised before operator=() is invoked, then the initial value is overwritten before it's used anyway, the optimiser may or may not be able to remove the first initialisation. For example:
std::string s_;
Q* p_;
int i_;
X(const X& rhs)
: p_(nullptr) // have to initialise as operator= will delete
{
// s_ is default initialised then assigned - optimiser may help
// i_ not initialised but if operator= sets without reading, all's good
*this = rhs;
}
As you can see, it's a bit error prone, and even if you get it right someone coming along later to update operator= might not check for a constructor (ab)using it....
You could end up with infinite recursion leading to stack overflow if getWeapon() uses the Prototype or Flyweight Patterns and tries to copy-construct the Weapon it returns.
Taking a step back, there's the question of why getWeapon(CHAIN_GUN); exists in that form. If we need a function that creates a weapon based on a weapon type, on the face of it a Weapon(Weapon_Type); constructor seems a reasonable option. That said, there are rare but plentiful edge cases where getWeapon might return something other than a Weapon object that can never-the-less be assigned to a Weapon, or might be kept separate for build/deployment reasons....
If you have defined a non-copy = assignment operator that lets the Weapon change its type after construction, then implementing the constructor in terms of assignment works just fine, and is a good way to centralize your initialization code. But if a Weapon is not meant to change type after construction, then a non-copy = assignment operator does not make much sense to have, let alone use for initialization.
I'm sure yes.
You already created object inside your "getWeapon" function, and then you copying it, that may be long operation. So, at least you have to try move semantic.
But.
If inside "getWeapon" you call to constructor (and you do, somehow "getWeapon" have to create your class to return it to your copy operation), you create very unclear architecture, when one constructor calls function that calls another constructor.
I believe you have to separate your parameters initialization to private functions, that have to be called from your constructors the way you want to.

Is it safe to "initialize" an object of type T with *this = T() in a constructor of T?

Is the constructor Year() safe in this case ?
struct Year {
int year;
Year(int y) : year(y) {}
Year() { *this = Year(1970); } // *this = this->operator=(Year(1970));
};
Year y;
I think yes, because year has already been initialized with int() once the execution flows reaches the constructor body. Are there other problems to consider?
Don't consider other cases in which the same trick might cause troubles.
Sure, this will work, and is valid.
Explanation
All data members and bases have already been constructed by the time your ctor-body runs, and:
[n3290: 12.7/4] Member functions, including virtual functions
(10.3), can be called during construction or destruction (12.6.2). [..]
Not to be confused with:
[n3290: 12.7/1] For an object with a non-trivial constructor, referring to any
non-static member or base class of the object before the constructor
begins execution results in undefined behavior.
(NB. "before the constructor begins"; this clause does not apply here.)
And there's nothing in 12.8 "Copying and moving class objects" to prohibit assignment during construction.
Caveat
Note that this does not mean that the object has begun its "lifetime":
[n3290: 3.8/1]: The lifetime of an object of type T begins when:
storage with the proper alignment and size for type T is obtained, and
if the object has non-trivial initialization, its initialization is complete.
And the final step in "initialization" for a non-delegating ctor:
[n3290: 12.6.2/10]: [..] Finally, the compound-statement of the constructor body is executed.
Put altogether, this means that an object's "lifetime" doesn't begin until its most derived constructor body has finished executing.
In particular, passing a pointer to the object before it has started its life is not very useful, as doing almost anything through that pointer invokes Undefined Behaviour:
[n3290: 3.5/8]: Before the lifetime of an object has started but
after the storage which the object will occupy has been allocated
or, after the lifetime of an object has ended and before the storage
which the object occupied is reused or released, any pointer that
refers to the storage location where the object will be or was located
may be used but only in limited ways. [..]
However:
[n3290: 3.8/3]: [..] [ Note: [..] Also, the behavior of an object
under construction and destruction might not be the same as the
behavior of an object whose lifetime has started and not ended. 12.6.2
and 12.7 describe the behavior of objects during the construction and
destruction phases. —end note ]
And, as we've already explored, 12.7 kindly informs us that members may be accessed during this phase of construction.
Suggestion
Your approach is hard to follow, though; I also had to look up the above passage before I could be sure that it's valid, so it's clearly not entirely intuitive.
Fortunately C++0x introduces constructor delegation, so that you can write:
struct Year {
Year() : Year(1970) {}
Year(int y) : year(y) {}
int year;
};
(Alas, GCC 4.5.1 doesn't support this, so I cannot demonstrate it to you on ideone.com. In fact, for GCC as a whole there's only a "partial patch" at time of writing.)
What you're doing works, but what wouldn't work would be if you somehow recursively called a constructor ... that would cause problems. But since the constructor is called after all non-static data-members of the object have been constructed, and the this pointer is pointing to valid memory that can be copied into, what you've done is okay--it's not standard practice, but it's okay.
This answer is probably wrong; see Tomalak's answer and the comments. I'll leave it for historic reasons, but you're probably OK calling member functions during the constructor.
Most definitely not. If you have any T*, say p, then you may only invoke member functions via p-> if p points to an object. But an object only begins its life when its constructor has finished. So while you're in the middle of the constructor, this does not point to an object! Therefore, you can most certainly not invoke any member functions like the assignment operator on this not-yet object.
[Curiosum: It is legit to say delete this; in certain situations, you just have to make sure that the destructor does not refer to this in any way. It is also OK to pass this to some other place during the constructor, as long as it is not dereferenced, much like you can pass any garbage pointer around as long as you don't use it.]

Why can't one ctor call another ctor to initialize the object

class Foo {
public:
Foo() { Foo(1)}
Foo(int x, int y = 0):i(x) {}
private:
int i;
}
Can anybody give me some reasonas about can I do this? If not why?
Because the language specification doesn't allow it. Just the way the language is. Very annoying if you're used to Java or other languages that allow it. However, you get used to it after a while. All languages have their quirks, this is just one of C++'s. I'm sure the writers of the specs have their reasons.
Best way around this I've found is to make a common initialization function and have both constructors call that.
Something like this:
class Foo {
public:
Foo() {initialize(1);}
Foo(int nX) { initialize(nx); }
private:
void initialize(int nx) { x=nx; }
int x;
};
It's a language design choice.
A constructor is a one time (per-object) operation that creates a new object in uninitialized memory. Only one constructor can be called for an object, once it has completed the object's lifetime begins and no other constructor can be called or resumed on that object.
At the other end of its life a destructor can only (validly) be called once per object and as soon as the destructor is entered the object's lifetime is over.
A prinicipal reason for this is to make explicit when an object destructor will be run and what state it can expect the object to be in.
If a class constructor completes successfully then it's destructor will be called, otherwise the object's lifetime has never begun and the destructor will not be called. This guarantee can be important when an object acquires resources in its constructor that need to be released in its destructor. If the resource acquisition fails then the constructor will usually be made to fail; if the destructor ran anyway it might attempt to release an resource that had never been successfully acquired.
If you allow constructors to call each other it may not be clear if a calling or a called constructor is responsible for the resource. For example, if the calling constructor fails after the called constructor returns, should the destructor run? The called constructor may have acquired something that needs releasing or perhaps that was what caused the calling construtor to fail and the destructor shouldn't be called because the resource handle was never valid.
For simplicity of the destruction rules it is simpler if each object is created by a single constructor and - if created successfully - destroyed by a single destructor.
Note that in C++11 a constructor will be able delegate to a different constructor, but there are limitations that don't really relax the principal of one construction per object. (The prinicipal constructor can forward to a target constructor, but if it does it must not name anything else (base classes or members) in its initializer list. These will be initialized by the target constructor, once the target constructor returns the body of the prinicipal constructor will complete (further initialization). It is not possible to re-construct any bases or members, although it allows you to share constructor code between constuctors.)
You cant do this. See section 10.3: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.3. You can try to do it but doing so will construct a new temp object (not this) and be destroyed once control moves on.
What you can do however is to create a private function that initializes variables, one that your default constructor or a parameterized constructor can both call.
There is a really hideous hack I have seen used to call another ctor. It uses the placement new operation on the this pointer. erk
Like this:
Class::Class(int x) : x_(x) {}
Class::Class() {
new (this) Class(0);
}
Class::Class(const Class &other) : x_(other.x_) {}
Class& operator=(const Class &other) {
new (this) Class(other);
return *this;
}
Note that I am not recommending this, and I don't know what horrible effects it might have on C++ structures like virtual base classes, etc. But I expect that there are some.
Although as per standards vendors are free to implement data binding in their own ways, if we consider the most popular implementation: this pointer, we can see a reason why this can't be implemented.
Assume you have a class:
class A
{
public:
A(){}
A(int a){}
} ;
With the this pointer implementation, this class would look something like:
class A
{
public:
A(A *this){}
A(A *this,int a){}
} ;
Typically you would create objects like this:
A ob ;
Now when compiler sees this, it allocates memory for this and passes the address of this allocated memory block to the constructor of A which then constructs the object. It would try to do the same every time for each constructor called.
Now when you try calling a constructor within another constructor, instead of allocating new memory the compiler should pass the current objects this. Hence inconsistency!
Then another reason which i see is that even though you might want to call a constructor within another, u would still want a constructor to call default constructors for all the objects within the class. Now if one constructor were to call another, the default construction should happen for the first constructor and not for the subsequent one's. Implementing this behavior means that there would be several permutations which need to be handled. If not, then degraded performance as each constructor would default construct all the objects enclosed.
This is what i can think of as possible reasons for this behavior and do not have any standards to support.