Constructor and Destructor for static member variable (a pointer) - c++

I am working on a class ex1 which needs one static member variable y. That static member variable is a pointer to an object of class ex2 which has its own constructor and destructor. Now I know how to initialize the variable y by defining it outside the class. But how to call the destructor for variable y? I need to use delete statement, but where to place that statement. I need to call both constructor and destructor of class ex2.
An equivalent code of my problem is shown below with the output:
#include<iostream>
class ex2 {
public:
int n;
ex2(int num) {
n = num;
std::cout << "Constructor of ex2\n";
}
~ex2(){std::cout << "Destructor of ex2\n";}
};
class ex1 {
public:
static ex2 *y; //static member variable
ex1() {std::cout << "Constructor of ex1\n";}
~ex1() {std::cout << "Destructor of ex1\n";}
};
ex2 *ex1::y = new ex2(90); //definition for static member
int main()
{
ex1 y1;
return 0;
}
The output for this is:
Constructor of ex2
Constructor of ex1
Destructor of ex1
Please help on how to call the destructor of ex2. Also the destructor need to be called after all instances of class ex1 are destroyed.

You could create regular class that on destructions calls delete on your pointer:
struct Destroyer {
ex2 *p;
~Destroyer() { delete p; }
};
ex2 *ex1::y = new ex2(90);
Destroyer dex2{ex1::y};
PS: In my experience you should avoid putting too much logic during automatic initialization and automatic destruction. There are things to pay high attention to (what parts of your system are still usable when doing the destruction? what parts are already usable during construction?) and moreover I discovered even tools like debuggers don't work well during those times. As a rule for example you should never ever do anything that can fail for whatever reason before main is started or after main is completed because that will be a pain to manage (how can you log an error during initialization if the error logging subsystem wasn't initialized yet? how can you log the error during shutdown if the logging system was already shut down?).
I also think the C++ standard specification is kind of fuzzy about those issues so you may get surprises depending on compilers and over the years I preferred moving away from lazy/automatic initialization and destruction to explicit initialization and destruction done in main in the sequence I want and that I know to be correct.

Related

Why is the order of destruction same as order of construction, with static object (C++)?

The code is :
#include <iostream>
using namespace std;
class A
{
public:
A() { cout << "A::A" << endl; }
~A() { cout << "A::~" << endl; }
};
class B
{
public:
B() { cout << "B::B" << endl; }
~B() { cout << "B::~" << endl; }
};
int main()
{
B b;
static A a;
return 0;
}
The output is :
B::B
A::A
B::~
A::~
The scope of non-static object b and the scope of static object a ends at the end of main() function.
Question : Why is the order of constructors is same as the order of destructors ?
Static local variables will be destroyed at program exit.
The destructor for a block-scope static variable is called at program exit, but only if the initialization took place successfully.
So b will be destoryed firstly at the end of main(), a will be destroyed after that.
For the initialization,
are initialized the first time control passes through their declaration
So b will be initialized firstly in main(), then a gets initialized.
Because they have different lifespans. A is declared as function-local static variable.
Object created by declaration of automatic function-local variable got lifespan which begins before any use of that object and ends with the most nested code block (braces block) containing that declaration. In your case that's function main() body.
Object created by declaration of static function-local variable begins to exist after execution flow had entered the most nested code block containing that declaration and before any use of that object.
It got process-wide life span (stops to exist at std::atexit()), which happens after the function main() will be exited.
SO they are created in this particular case in order of declaration, but A will get destroyed way later. If your function was called twice, you'd see that B would be created twice but A only once. If function's flow would somehow omit either declaration, by if() statement or by returning early, the order of their creation of would change or both may be omitted.
It's implementation specific detail, but usually destruction of function-local statics implemented in same way as destruction of global objects, by call to a library function that lies under implementation of std::atexit, adding the address of destructor bound with value of pointer to object itself, but the execution may be concurrent (or may be not) with result of user's calls of std::atexit.
As addition to already existing answers, lets take a more phenomenological approach. Consider a small change on your example:
void foo() {
B b;
static A a;
}
int main() {
foo();
foo();
}
I assume you know that a is initialized only once and on the second call we get the exact same object a, because it is declared as static. Hence, it cannot be destroyed during or directly after the first call to foo. The expected first part of the output is
B::B // first call to foo()
A::A
B::~
B::B // second call to foo()
// no second call to A::A !
B::~
a can only be destroyed when your program terminates, otherwise you could not "reuse" it when calling the function again (thats why I had to modify the example, you cannot call main). As other answers explain in great detail, this happens after main returns. Hence last line of output will be
A::~

How to call parameterized constructor of member object variable in a class' default constructor in C++?

I want to initialize member object variables in the default constructor of the class.
Let's consider the following,
class ABC {
ABC(int A, int B) {
a = A;
b = B;
}
int a;
int b;
};
class Foo {
Foo();
ABC m_obj1;
};
From the above example, I would like to initialize "obj1" in "Foo::Foo()".
One of the restrictions I have is that I cannot do so in the initializer list, as I need to do some computation before I could initialize the member. So the option available (ASFAIK) is to do so in the body of the default constructor only.
Any inputs, how could I do this?
Edit: Restricting to C++11
Would this be a correct way,
Foo:Foo() {
int x = 10;
int y = 100;
m_Obj1(x, y); //Is this correct? <--------
}
Depending on your exact problem and requirements, multiple solutions might be available:
Option 1: Use a function to do the computations and call Foo constructor
Foo makeFoo()
{
// Computations here that initialize A and B for obj1 constructor
return Foo(A, B)
}
Option 2: Call a function that does the computations and initialize obj1 in Foo member initializer list
ABC initABC() {
// Some computations
return ABC(A, B)
}
Foo() : obj1(initABC()) {}
Option 3: Dynamically allocate obj1, for instance with a std::unique_ptr
Option 4: Use std::optional or an emulated c++11 version as shown by other answers
You simply call the base constructor inside the initializer list of the derived constructor. The initializer list starts with ":" after the parameters of the constructor. See example code!
There is no problem to call functions inside the initializer list itself.
int CallFunc1(int x) { return x*2; }
int CallFunc2(int y) { return y*4; }
class ABC {
public:
ABC(int A, int B):a{CallFunc1(A)},b{CallFunc2(B)} {
std::cout << "Constructor with " << a << " " << b << " called" << std::endl;
}
private:
int a;
int b;
};
class Foo {
public:
Foo(): obj1(1,2){}
Foo( int a, int b): obj1(a, b){}
private:
ABC obj1;
};
int main()
{
Foo foo;
Foo fooo( 9,10);
}
edit:
The best method I can think of for your case is a copy constructor, being more specific on what you need to store helps a lot since if it is just two ints inside a class dynamic allocation is not worth it, the size of the object being constructed makes a difference to what method is best, copy constructors can be slower with much larger data types as the object has to be created twice: once when it is automatically constructed in the parent objects constructor and again when a temporary object is created and all the values have to be copied, which can be slower then dynamically allocating if the size is larger.
As far as I'm aware all objects in a class are automatically initialized/allocated in the constructor so sadly dynamic memory use may be your best bet here.
If you are fine with having the object initialized but empty so you know it is not 'ready' yet you can later fill it with useful data when you would have wanted to initialize it. This can be done with default constructors that set the things inside the object to null values or something similar so you know the object hasn't been properly initialized yet. Then before using the object you can check whether it has been initialized by checking for the null values or by having put a bool in the object that tells you whether it is initialized. Dynamically allocated would still be better in my opinion and makes the code look cleaner overall as all you need to store is a null pointer until the object is needed and then allocated and set to the pointer. It is also very easy to check if the pointer is equal to nullptr to know the state of your object.
Dynamically allocating memory may be a hassle since you have to make sure to get rid of memory leaks and it is slightly slower than using the stack, but it is a necessary skill for c++ since the stack is not enough when making programs that use more than the few available megabytes of data on the stack so if you are doing this simply to avoid the hassle I recommend learning it properly. It would be nice if you could be more specific about what kind of object you want to do this with or if you just want an answer that works for most cases.
eg:
*ABC obj1 = nullptr;
...object is needed
obj1 = new(ABC(constructor stuff));
...obj1 isn't needed
delete obj1;
or c++ automatically deletes it when the program closes.

Calling a constructor of the base class from a subclass' constructor body

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
}
};

What does empty destructor do?

I heard that empty destructor doesn't do anything and calling it doesn't remove the object.
But in the code:
#include <iostream>
#include <set>
class a
{
public:
~a()
{}
std::set <int> myset;
};
int main()
{
a object;
object.myset.insert(55);
object.~a();
object.myset.insert(20);
std::cout << object.myset.size();
}
I get:
"* glibc detected * /.app: double free or corruption (fasttop):" and then "ABORT".
If it matters I have c++11 flag enabled. So what does empty constructor actually do? It does something and I read it doesn't.
Your destructor may look empty, but it's actually destructing the member variables. In this case, it's destructing myset, so the subsequent insert(20) is crashing.
If your class had no non-POD member variables then the empty destructor would truly do nothing.
Your question mentions a couple different issues.
First, there's the error message. The "Double free" is probably because the destructor is getting called twice: once by you, and once by the C++ runtime when the variable is no longer in scope (at the closing brace of your main function).
Second, there's your question about the empty destructor not removing the object. Indeed it does not remove the object from memory, but it DOES destroy its member variables. So after your manual call to the destructor, the memory for object is still allocated, but myset is no longer valid.
Destructor is called when going out of scope. I would highly recommend not calling the destructor, and then attempting to access members or member functions of the parent class. Since your class has member variables myset, it's deallocating those when being manually called, hence the segmentation error.
Think of the destructor as the "clean up" when you're absolutely done with your object. Under no circumstances should you call it manually.
Pseudocode:
class MyClass {
public:
MyClass() {
std::cout << "Constructor" << std::endl;
}
~MyClass() {
std::cout << "~Destructor" << std::endl;
}
}
int main(int argc, char** argv) {
MyClass myClass;
return 0;
}
You should see this output:
Constructor
~Destructor
As you can see, no manual call is needed.

Meaning of "~" (tilde) symbol in C++?

// AirlineTicket.h
class AirlineTicket
{
public:
AirlineTicket();
~AirlineTicket();
int getNumberOfMiles();
private:
int mNumberOfMiles;
};
I want now what is the meaning of ~AirlineTicket(); in this code?
I don't know the meaning of ~ (tilde).
It is the destructor.
It gets called when you destroy (reaching end of scope, or calling delete to a pointer to) the instance of the object.
In the context you're using it, it defines a destructor.
In other context such as the following one, it's also called bitwise negation (complement):
int a = ~100;
int b = ~a;
Output: (ideone)
-101
100
~ signs that it is a destructor and when ever the object goes out of scope, corresponding destructor is called.
When the destructor is called ?
Taking an example -
#include <iostream>
class foo
{
public:
void checkDestructorCall() ;
~foo();
};
void foo::checkDestructorCall()
{
foo objOne; // objOne goes out of scope because of being a locally created object upon return of checkDestructorCall
}
foo:: ~foo()
{
std::cout << "Destructor called \t" << this << "\n";
}
int main()
{
foo obj; // obj goes of scope upon return of main
obj.checkDestructorCall();
return 0;
}
Results on my system:
Destructor called 0xbfec7942
Destructor called 0xbfec7943
This example just serves to indicate when a destructor is called. But destructor is written only when the class manages resources.
When class manages resources?
#include <iostream>
class foo
{
int *ptr;
public:
foo() ; // Constructor
~foo() ;
};
foo:: foo()
{
ptr = new int ; // ptr is managing resources.
// This assignment can be modified to take place in initializer lists too.
}
foo:: ~foo()
{
std::cout << "Destructor called \t" << this << "\n";
delete ptr ; // Returning back the resources acquired from the free store.
// If this isn't done, program gives memory leaks.
}
int main()
{
foo *obj = new foo;
// obj is pointing to resources acquired from free store. Or the object it is pointing to lies on heap. So, we need to explicitly call delete on the pointer object.
delete obj ; // Calls the ~foo
return 0;
}
Results on my system:
Destructor called 0x9b68008
And in the program, you posted I don't see a need to write destructor. Hope it helps !
It's the class destructor. You might want to pick up an introductory text on C++ development, as destructors are a fundamental concept in OOP. There is a good reference site here, and the C++ FAQ is another good resource.
~AirlineTicket(); is the destructor for the class AirlineTicket
see this link for further reference
The destructor is called when you delete the object of that class, to free any memory allocated or resources being used by the object.
~ introduces a destructor. It's used because (a) it was available, ad (b) ~ is one (of several) mathematical notation for "not".
This indicates destructor of class.
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr380.htm