It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
i would love to understand how this one works!
if i have this code for example
class myclass
{
public :
int a;
myclass(){a=0; cout<<"first"<<endl;}
myclass(int i){a=i;cout<<"second"<<endl;}
~myclass(){cout<<a<<endl;}
};
class yourclass:protected myclass
{
int x;
myclass m1;
public:
myclass m2;
yourclass (int i): m2(3),myclass(i){x=i; a=7;}
}
and i'll make an object like this
yourclass ob1(5);
can you please explain how to works? how to calls constructors ?
Thank you
When you declare an object of a class myclass like this:
myclass ob1(5);
it means that you've created it with the second constructor which accepts int parameter. In other words, you literally called the second constructor. By the way the object is created on stack.
When you declare an object of a class myclass like this:
myclass ob1;
it means that you've created it with the first constructor which is parameterless. The right term for parameterless constructor is default constructor. In other words, you literally called the default (the first one) constructor. By the way the object is created on stack too (as in the previous case).
When objects are created on stack they are destructed automatically when the object goes out of scope. The notion of scope applies to the blocks of code which include functions/methods/blocks. You can easily distinguish the block by a pair of curly brackets {}. For example:
void function() {
myclass ob1;
} // <--- think of ob1 being destructed at this point
the object ob1 will go out of scope when function finishes execution and accordingly the destructor for ob1 is automatically called. Another example:
void function() {
while(true) {
myclass ob1;
} // <--- think of ob1 being destructed at this point
// ob1 does not exist here!
}
notice the infinite loop and the object ob1 created inside it on every iteration. You can clearly see that curly brackets define a block which can combine multiple statements that constitute each iteration (currently there is only 1 statement). Accordingly, the object ob1 will be automatically destructed in the end of each iteration.
The notion of scope applies to class members too. For instance, say you have a class wrapper, and you declare myclass as its member (m1) in the following way:
class wrapper {
public:
myclass m1;
};
Then lets take one of the previous examples and create an object of wrapper on stack:
void function() {
wrapper w;
} // <--- destructor of w called first, destructor of w.m1 is called after
First the execution of the default constructor of w is started, during which w.m1 is created (with default constructor in this case because I didn't specify in the constructor of w which constructor of w.m1 I'd like to call). Then the constructor of w finishes the execution, and w can be deemed as officially created. The execution of function continues.
When function finishes execution, w goes out of scope, and as you remember its destructor is called automatically then. As soon as the destructor of w finishes the execution, the destructor of w.m1 is automatically called too. You can think of it as the object w has its own internal scope while it's alive, and a soon as it dies, all of its members go out of scope and should die too.
Ok, let's take it easy and analyze it step by step.
First class
class myclass {
public :
int a;
myclass(){a=0; cout<<"first"<<endl;}
myclass(int i){a=i;cout<<"second"<<endl;}
~myclass(){cout<<a<<endl;}
};
Here we are defining a class myclass which have a single member variable a of type int. It declares a default constructor (with no arguments) which assigns to a, 0 and then proceed to print first.
We also have a one-parameter constructor that initialize a to that first parameter, and prints second, and a destructor which simply prints the value of the member variable a before deallocating it.
Initialization list
Now, within constructors you can define an initialization list which is on the form
<class name>(...) a(x), b(y), c(z), ... {}
// ^^^^^^^^^^^^^^^^^^^^^
This initialization list is necessary when there's no default constructor available for the type of any member variable of the class. Suppose we create a nogood class without a default constructor and define our main class to have a member of type nogood, how would he initialize that member variable? You can expect it to wait until the constructor body is executed.
Second class
class yourclass : protected myclass {
int x;
myclass m1;
public:
myclass m2;
yourclass (int i): m2(3),myclass(i){x=i; a=7;}
};
Now yourclass inherits protected from myclass. What does it means? It means that whatever in myclass is public or protected, will be protected in yourclass (whatever is private will still be private).
The class yourclass defines two private members x and m1 and one public member m2. It doesn't define any default constructor for it and defines a single parameter constructor instead (that can actually be also used to implicitly convert an int to yourclass if required).
Output: constructors
Firstly it calls the protected sub object's constructor producing second.
Then, since we haven't initialize m1 explicitly, it will initialize it with the default constructor producing the output first.
Finally in the constructor we initialize m2(3) which is of type myclass which will call myclass::myclass(int) producing second as output. So the output is:
second
first
second
Output: destructors
Now for the destructors calls, it will call the destructors for each member variables in the reverse order to their initialization. The order of initialization was: m1, m2. The reverse order is m2, m1. m2 was initialized with 3 in the initialize list, m1 was initialized to 0 by default. Then finally it calls the ob1 destructor which was initialized to 7. Therefore the final output is:
second
first
second
3
0
7
Related
So if I have something like the following:
class MyClass{
public:
MyClass(){
// do other stuff
*oc = OtherClass(params);
}
private:
OtherClass* oc;
}
When is a constructor called on OtherClass? Would its default be called once as soon as the MyClass initialization begins, and then be redefined with its value constructor during the MyClass constructor? Or does it just not exist during "//do other stuff". What if no default constructor is provided for other class, only a value? Would it be good practice to construct it where it is defined as a member variable?
A default constructor is one that can be called without parameters. For example this is a default constructor:
struct foo {
foo(){} // (should not actually be user defined)
};
This is also a default constructor:
struct bar {
bar(int x = 42) {}
};
In your code it might be that the constructor that is called is a default constructor, but it does not matter for your code, because you do pass a parameter.
When is a constructor called on OtherClass?
In the line *oc = OtherClass(params);.
Would its default be called once as soon as the MyClass initialization begins, and then be redefined with its value constructor during the MyClass constructor?
If you do not provide an initializer members are default initialized. Confusingly for a pointer this means it is not initialized.
Or does it just not exist during "//do other stuff".
The member does exist before, but its value is indeterminate. You cannot use the value without invoking undefined behavior.
What if no default constructor is provided for other class, only a value?
See above. The existance of a default constructor of OtherClass is not relavant here. It would be relevant if the member was OtherClass and not a pointer, because for members of class type default initialization calls the default constructor.
Would it be good practice to construct it where it is defined as a member variable?
It is good practice to provide an initializer for members rather than assign in the constructor:
class MyClass{
public:
MyClass() : oc(params) {
}
private:
OtherClass oc;
}
I replaced the member with an instance rather than a pointer, because using a raw pointer as member opens up a can of worms that would require an even longer answer. For more on that read What is The Rule of Three?. Note that when the member is not a pointer but a OtherClass then suddenly it matters if OtherClass has a default constructor, because if you do not provide an initializer, then the member will be default constructed. Though in the above I used the member initializer list and the member will be initialized by the constructor that takes one parameter.
ÓtherClass *oc; is a pointer and as such has no constructor. It has to be initialized to a valid object before you can dereference it.
You can ensure oc is initialized by, well, initializing it:
MyClass() : oc(new OtherClass()) {
...
*oc = OtherClass(params);
}
This will create a dummy oc when the class it created and then copy or move assign the real object to *oc later. This is wasteful, so why not initialize it with the final value directly:
MyClass() : oc(new OtherClass(params)) {
...
}
or if you have to compute params first:
MyClass : oc(nullptr) {
...
oc = new OtherClass(params);
}
Initializing oc with nullptr first isn't required but it is dirt cheap and it ensures accidentally using oc will access a nullptr and fail instead of oc being some random value that might not crash.
You can also, and better, ensure initialization by inlineing that:
class MyClass {
...
private:
OtherClass *oc(nullptr);
}
With that the compiler will initialize oc whenever you don't initialize it in an initializer list in the constructor.
That said: Do you really need a pointer there? You need a destructor, copy/move constructors and aissgnment operators to handle the pointer directly. An Otherclass oc; would be much easier to deal with.
But if you do need a pointer then you should use a smart pointer to handle ownership for you. That means use std::unique_ptr or more likely std::shared_ptr for it. You might not even need anything past the constructor that way. But think about what it means for copy/move to have the pointer shared. Read about the rule of 0/3/5.
I was under impression that it's impossible, see for example:
Calling the constructor of the base class after some other instructions in C++
But the following program runs and produces two lines of "Constructor Person":
#include <iostream>
class Person
{
public:
Person()
{
std::cout << "Constructor Person" << std::endl; }
};
class Child : public Person
{
public:
Child()
{
c = 1;
Person();
}
int c;
};
int main()
{
Child child;
return 0;
}
The first one is implicit call of the default constructor, that's clear. What about the 2nd one - does it mean that the action described in the title is legitimate? I use Visual C++ 2010.
The call inside the child class constructor is not calling the base class constructor, it is creating a temporary, unnamed and new object of type Person. It will be destroyed as the constructor exits. To clarify, your example is the same as doing this:
Child() { c = 1; Person tempPerson; }
Except in this case, the temporary object has a name.
You can see what I mean if you modify your example a little:
class Person
{
public:
Person(int id):id(id) { std::cout << "Constructor Person " << id << std::endl; }
~Person(){ std::cout << "Destroying Person " << id << std::endl; }
int id;
};
class Child : public Person
{
public:
Child():Person(1) { c = 1; Person(2); }
int c;
};
int main() {
Child child;
Person(3);
return 0;
}
This produces the output:
Constructor Person 1
Constructor Person 2
Destroying Person 2
Constructor Person 3
Destroying Person 3
Destroying Person 1
The following is an excerpt from "Accelerated C++":
"Derived objects are constructed by:
1. Allocating space for the entire object (base class members as well as derived class members);
2. Calling the base-class constructor to initialize the base-class part of the object;
3. Initializing the members of the derived class as directed by the constructor initializer;
4. Executing the body of the derived-class constructor, if any."
Summarizing the answers and comments: Calling a constructor of the base class from a subclass' constructor body is impossible in the sense that #2 above must precede #4.
But we still can create a base object in the derived constructor body thus calling a base constructor. It will be an object different from the object being constructed with the currently executed derived constructor.
You can't call it from the body of the child constructor, but you can put it into the initializer list:
public:
Child() : Person() { c = 1; }
Of course it's not helpful to call the default constructor of the parent because that will happen automatically. It's more useful if you need to pass a parameter to the constructor.
The reason you can't call the constructor from the body is because C++ guarantees the parent will be finished constructing before the child constructor starts.
The answers to this question while usually technically true and useful, don't give the big picture. And the big picture is somewhat different than it may seem :)
The base class's constructor is always invoked, otherwise in the body of the derived class's constructor you'd have a partially constructed and thus unusable object. You have the option of providing arguments to the base class constructor. This doesn't "invoke" it: it gets invoked no matter what, you can just pass some extra arguments to it:
// Correct but useless the BaseClass constructor is invoked anyway
DerivedClass::DerivedClass() : BaseClass() { ... }
// A way of giving arguments to the BaseClass constructor
DerivedClass::DerivedClass() : BaseClass(42) { ... }
The C++ syntax to explicitly invoke a constructor has a weird name and lives up to this name, because it's something that's very rarely done - usually only in library/foundation code. It's called placement new, and no, it has nothing to do with memory allocation - this is the weird syntax to invoke constructors explicitly in C++:
// This code will compile but has undefined behavior
// Do NOT do this
// This is not a valid C++ program even though the compiler accepts it!
DerivedClass::DerivedClass() { new (this) BaseClass(); /* WRONG */ }
DerivedClass::DerivedClass() { new (this) BaseClass(42); /* WRONG */ }
// The above is how constructor calls are actually written in C++.
So, in your question, this is what you meant to ask about, but didn't know :) I imagine that this weird syntax is helpful since if it were easy, then people coming from languages where such constructor calls are commonplace (e.g. Pascal/Delphi) could write lots of seemingly working code that would be totally broken in all sorts of ways. Undefined behavior is not a guarantee of a crash, that's the problem. Superficial/obvious UB often results in crashes (like null pointer access), but a whole lot of UB is a silent killer. So making it harder to write incorrect code by making some syntax obscure is a desirable trait in a language.
The "second option" in the question has nothing to do with constructor "calls". The C++ syntax of creating a default-constructed instance of a value of BaseClass object is:
// Constructs a temporary instance of the object, and promptly
// destructs it. It's useless.
BaseClass();
// Here's how the compiler can interpret the above code. You can write either
// one and it has identical effects. Notice how the scope of the value ends
// and you have no access to it.
{
BaseClass __temporary{};
}
In C++ the notion of a construction of an object instance is all-permeating: you do it all the time, since the language semantics equate the existence of an object with that object having been constructed. So you can also write:
// Constructs a temporary integer, and promptly destructs it.
int();
Objects of integer type are also constructed and destructed - but the constructor and destructor are trivial and thus there's no overhead.
Note that construction and destruction of an object this way doesn't imply any heap allocations. If the compiler decides that an instance has to be actually materialized (e.g. due to observable side effects of construction or destruction), the instance is a temporary object, just like the temporaries created during expression evaluation - a-ha, we notice that type() is an expression!
So, in your case, that Person(); statement was a no-op. In code compiled in release mode, no machine instructions are generated for it, because there's no way to observe the effects of this statement (in the case of the particular Person class), and thus if no one is there to hear the tree fall, then the tree doesn't need to exist in the first place. That's how C++ compilers optimize stuff: they do lot of work to prove (formally, in a mathematical sense) whether the effects of any piece of code may be unobservable, and if so the code is treated as dead code and removed.
Yeah, I know this is a year old but I found a way to do it. This may not be the best practice. For example, destroying the base class instance from within the derived class constructor sounds like a recipe for disaster. You could skip the destructor step, but that may lead to a memory leak if the base class constructor does any allocation.
class Derived : public Base
{
public:
Derived()
{
// By the time we arrive here, the base class is instantiated plus
// enough memory has been allocated for the additional derived class stuff.
// You can initialize derived class stuff here
this->Base::~Base(); // destroy the base class
new (this) Base(); // overwrites the base class storage with a new instance
}
};
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
What methods are called when we create an object of a class in c++ or what exactly happens when we create an object of a class.
Without additional information, you should assume that one and only one member function of the class itself is called, the constructor.
class CheesePizza {
public:
CheesePizza() {}
};
CheesePizza barely; // will initialize by calling Foo::foo().
There are many cases in which additional functions might be called, for instance if you create a conversion scenario where a temporary object must be created, such as specifying a std::string argument and passing a const char* value.
class DIYPizza {
std::string m_toppings;
public:
DIYPizza(const std::string& toppings) : m_toppings(toppings) {}
};
DIYPizza dinner("all of the toppings");
This has to create a temporary std::string from the const char* argument, "all of the toppings". Then the DIYPizza::DIYPizza(std::string) operator can be passed this temporary (rvalue), and then subsequently we initialize m_str from it which invokes the std::string(const std::string&) copy constructor to initialize m_str.
What essentially gets done is:
// create a std::string object initialized with the c-string.
std::string rvalueString = std::string("all of the toppings");
// now we have a string to pass to DIYPizza's constructor.
DIYPizza dinner(rvalueString);
However - we're still only calling ONE member function of Foo at this point. The only way for more class members to be invoked is by calling them from whichever constructor is invoked.
class DinnerAtHome {
void orderPizza();
void drinkBeer();
void watchTV(); // I was going with something more brazen, but...
public:
DinnerAtHome() {
orderPizza();
drinkBeer();
watchTV();
drinkBeer();
// arrival of pizza is handled elsewhere.
}
};
Now when you construct a new DinnerAtHome, 5 member functions will be invoked: DinnerAtHome::DinnerAtHome() and the four member-function calls it makes.
Note: "new" is not a member function, it is a global operator.
IF the answer was "five" then either the interviewer was using a trick question or you missed some nuance of what was being asked.
Ok I try overkill answer since no once already selected an answer:
When you create an object the constructor is called, this also involves a call to underlying constructors of members objects, if the object inherits from another object you need also to call constructors of base classes
class Foo: public Bar{
std::vector<int> indices; //default constructor for indices is called
public:
Foo(int a):Bar(a){ //you have to call constructor of Bar here
//else compiling error will occur
}
};
Default constructor is called implicitly for objects that has it. When you create something with "new", first memory is allocated then object is constructed on top of that memory (placement new works in a similiar way, but the chunk of memory may be created explicity by the user elsewhere).
Note that in certain cases you don't know order of constructors calls:
CASE 1
Obj1* myobj= new Obj1 ( new Obj2, new Obj3( new Obj4) );
in this case you have no clues if Obj4 is created before or after Obj2 and if Obj3 is created before or after Obj2, simply the compiler will try to choose "an order" (that may vary depending on compiler and platform), also this is a highly unsafe code:
assume you get exception in Obj3 when Obj2 was already created, then Obj3 memory will never get deallocated (in that extreme case you may find usefull tools for those kinds of problems : Hypodermic / Infectorpp )
see also this answer
CASE 2
static/global variables may be initialized in different orders, and you have to rely on specific compiler functions to declare a initialization order
for GCC:
void f __attribute__((constructor (N)));
also note that "Constructor" is not a "method" like others, infact you cannot save constructor in a std::function nor bind it with std::bind. The only way to save a constructor is to wrap it with a factory method.
well that should be 5 "things" as you mentioned in the interview.
Lets assume your class is called CMyClass.
#include "MyClass.h"
/* GLOBAL objects */
static CMyClass g_obj("foo"); // static makes this object global to this file. you can use it
// anywhere in this file. the object resides in the data segment
// (not the heap or the stack). a string object is created prior
// to the constructor call.
int main(void)
{
....
if (theWorldEnds)
{
/* STACK */
CMyClass obj1; // this calls the constructor CMyClass(). It resides on the stack.
// this object will not exist beyond this "if" section
CMyClass obj2("MyName"); // if you have a constructor CMyClass(string&), the compiler
// constructs an object with the string "MyName" before it calls
// your constructor. so the functions called depend on which
// signature of the constructor is called.
/* HEAP */
CMyClass *obj3 = new CMyClass(); // the object resides on the heap. the pointer obj3
// doesn't exist beyond the scope of the "if" section,
// but the object does exist! if you lose the pointer,
// you'll end up with a memory leak. "new" will call
// functions to allocate memory.
}
}
If you are creating a class means you are calling constructor of that class. If constructor is not in your code than compiler will add the default constructor. YOu can override default constructor to perform some task on object creation.
For
Example:
If you are creating a object of type Person
Person* objPerson = new Person();
It means you are calling Person() method(constructor) of that class.
class Person {
public:
Person() {
// ...
}
};
When an object of a class is instantiated : memory required by the object of the class (depending on its data members) is allocated on the heap and a reference to that memory location is stored by the object name. This individual data members at this memory location on the heap may or may not be initialized depending on the constructor called.
When a new object is constructed, the constructor of the class is invoked to initialize non-static member variables of the class (if the class does not have any constructors, compiler assigns a an empty constructor for the class and invokes it). The constructor may invoke other functions (either library or user-defined functions), but that depends on the functions that programmer has invoked inside the constructor. Also, if the class is part of an inheritance hierarchy, appropriate constructor of base classes are called by compiler before the constructor of the class being instantiated (visit here for a brief explanation).
Having a simple class:
class A {
public:
A() {}
void set(int value) { value_ = value; }
private:
int value_;
};
and its global instance:
A a;
Is it OK to call method set on a not yet constructed object a? That can happen when for example a.set(123) is called from a constructor of another global object in another translation unit.
Will the value in the object a set by calling a.set(123) remain when the non-parametric and empty constructor of A is later called for object a?
Is it ok to call method set on a not yet constructed object a?
No. You may not call member functions for an object that has not yet begun construction.
(Since the answer is no, your second question requires no answer.)
If you may need to access this global instance from multiple translation units during dynamic initialization, you can use the Meyers singleton technique:
A& global_a()
{
static A a;
return a;
}
a will be initialized when global_a() is first called. Note that in a multithreaded program you may need to concern yourself with synchronization of the initialization.
When you write
A a;
a is a constructed object now. In case A is a then A default constructor was already been called
If in 1) you mean it's ok to call set in the constructor, then yes, that's fine because it isn't a virtual method. You cannot call a virtual method in the constructor.
As for 2), what you're asking isn't really clear. The constructor is only called once (although there are ways around that sort of thing, but don't do them) and that is when the object is first created. You can't call the constructor on a a second time so the question doesn't really make sense.
I have a global member data object, defined in a header (for class MyMainObj) like this.
class MyMainObj
{
MyDataObj obj;
}
MyDataObj has a default constructor.
When is the constructor for MyDataObj called?
Is it called as part of the creation of MyMainObj?
MyDataObj in this case is not a member of MyMainObj, it's a local variable.
But, constructors for data members are called in your class's constructor. The default constructor for every member is called before execution reaches the first line in the constructor, unless you explicitly specify a constructor using an initializer list, in which case that constructor is called instead.
With that code, obj isn't a member of MyMainObj -- it's simply a local object inside that constructor. As such, it'll only be constructed when/if that constructor is invoked.
Concerning your code, you have a function with a variable inside. Upon entering the function, you will run to the line of code that declares the variable, and the constructor will be run then.
But you say "creation of MyMainObj". It's a function, it can only be called, not created.
This is all concerning the title question, "when are members constructed?" This would apply if MyMainObj was a class and not a function.
Your member objects are constructed in the order of which they appear in the class declaration. All objects are full constructed upon entering the constructor. (But this does not include the class itself!)
That is to say, by the time the class enters its constructor, all the members have finished their constructor.
Objects are destructed in reverse order, in the destructor (after the destructor is run).
In a pseudo-diagram:
MyClass
Member1
Member2
Member3
Construction:
Member1
Member2
Member3
MyClass
Destruction:
MyClass
Member3
Member2
Member1
You can manually call the members constructor using an initialization list:
class foo
{
public:
foo(void) : i(0) // construct i with 0.
{
}
int i;
};
There are various question on SO about initialization lists. Initialization list order, Copy-construction initialization list, and more.
Yes, the constructor would be called whenever a MyMainObj instance is created.
I'm a bit confused by the "global member" terminology - the way you've declared that object it would be a local variable inside the constructor. Am I missing something here?
Yes, as other stated the member will be created on the owner class creation, on construction (be it generated by the compiler or with a provided constructor).
The order of creation will be the same as how your members apear in the class declaration. For example :
class MyType
{
Thing a;
Thing b;
Thing d;
Thing c;
};
Whatever constructor is used, whatever the order in a initialization list, the members will be constructed in this order : a, b, d, c. Once it's all done, the constructor code will be executed (if it exists) and only then your whole object will be constructed.
Upon entering an object constructor, memory has already been allocated for it. Then the execution order is as follows:
Base class constructor, if any, as specified in the initialisation list; if not specified, the default constructor is used.
The constructors for the member data, as specified in the initalisation list (default if not specified), in the order they are declared in the class definition. The order in which they are specified in the initialisation list is irrelevant.
The constructor body.
In the example set in the question, the first thing that would be executed upon entering the default constructor of MyMainObj would be the default constructor of MyDataObj to construct the member data obj.
Given a class A:
class A {
MyDataObj obj;
}
If you don't write the constructor for A, the compiler will create one for you, which will create obj as part of constructing A (and destroy obj as part of destroying A.
If you do write a constructor for A, then obj will be created before your constructor runs, although you can reassign it:
class A {
MyDataObj obj;
public:
A() { } // obj created, but the value may or may not be predictable
}
class AA {
MyDataObj obj;
public:
AA()
{
obj = MyDataObj(5);
}
}
class AAA {
MyDataObj obj;
public:
AAA() : obj(5) { } // member initializer list, my preferred method
}
With the third option, the data objects are created before the member initializer list runs, and the values are assigned in the order they are declared in AAA, NOT the order they are listed in the member initializer list.
UPDATE: There is a difference between creation and initialization. Space for the data members (and the base classes, and the data members for the base classes) is always set aside -- which I would call "creation." However, that doesn't mean a useful value is stored in that memory. There are separate rules for whether an object is default initialized, which depend on the type of the data member (primitive, POD, non-POD) and, IIRC, the storage class of the main object (local, static, global). The easiest way to avoid surprises in this area is to simply make sure you explicitly initialize everything.