#include<iostream>
using namespace std;
class Test
{
public:
static int Retr(); // Static member function
//~Test(); // Test destructor
Test(); // Default constructor
private:
static int count; // Static member variable
int i;
};
int Test::count = 0; // Initialization
int main()
{
Test obj;
cout << Test::Retr() << endl;
// The result should be 1 but prints two
return 0;
}
Test::Test() : i(1) { Retr(); }
int Test::Retr()
{
return ++count;
}
/*
Test::~Test()
{
count--;
}
*/
I'm practising about usage of static member function and variable. I have a static member function that counts and returns how many objects are constructed. It should show 1 for this example but it shows 2. I don't understand why it happens. However, the destructor decreases the counter end of scope for every constructed objects. Doesn't it? So, the result using with destructor should be 0. But, I can't get the expected results. Could someone explain?
Edited what about not working of destructor ? Solved
#include<iostream>
using namespace std;
class Test
{
public:
static int Retr(); // Static member function
~Test(); // Test destructor
Test(); // Default constructor
private:
static int count; // Static member variable
int i;
};
int Test::count = 0; // Initialization
int main()
{
Test obj[2];
cout << Test::Retr() << endl;
// The result should be 0 because of destructor but prints 2
return 0;
}
Test::Test() : i(1) { ++count; }
int Test::Retr()
{
return count;
}
Test::~Test()
{
--count;
cout << Test::Retr() << endl;
}
Test::Test() : i(1) { Retr(); }
When you have created an object, It also calls retr() function. Thats increments count; And again you call retr() to show..
Your destructor is working.Call Test::Retr() to check count after destruction.
Test::~Test()
{
--count;
cout << Test::Retr() << endl;
}
First things first, you need to understand what is a static member function.
Static members of a class are not associated with the objects of the class: they are independent objects with static storage duration or regular functions defined in namespace scope, only once in the program.
So your entire program will only have one instance of count (Which is initialized to 0)
Let us look at the code in the main function, you're creating an object of the class Test. Hence the constructor gets called, which inturn calls the static int Retr() function. Hence count is now 1. Now,
cout << Test::Retr() << endl;
Calls Retr() again, hence it increments count and returns the value. Hence 2 is returned.
As far as the destructor is concerned, it is not called before the cout. It will be called only when obj goes out of scope, which will happen only when the main function is completed.
When you are creating
Test obj;
It calls the constructor and increments 1
and again you are calling
Test::retr()
It also increments 1.
If you want to check the behavior of your class you can add additional function as
void testFunction(){
Test obj[2];
std::cout << Test::Retr() << std::endl; // count became 3
}
int main(){
testFunction();
// Obj destructed here count became 1
std::cout << Test::Retr() << std::endl;
// It will again increment and count will be 2
}
Related
English is not my native language,so please forgive me for my grammar problems.
When I run my program, I find that class constructors are called when defining objects and explicitly calling constructors。After calling the constructor and after leaving the scope, the destructor is called twice。
#include<iostream>
class test {
private:
int a;
int b;
int c;
public:
test(int first = 0, int second = 0, int third=0 );
void show();
~test();
};
void test::show() {
std::cout << this->a<<"\n";
}
test::test(int first , int second , int third ) {
this->a = first;
this->b = second;
this->c = third;
std::cout << "Construct\n";
}
test::~test() { std::cout << "destruct\n"; }
extern test myclassone;
#include <iostream>
#include "myhead.h"
test myclassone;
int main()
{
std::cout << "begain\n";
{
std::cout << "mid\n";
myclassone = test(1,1,1);
std::cout << "mid\n";
myclassone.show();
}
std::cout << "end\n";
}
The output of this program is
Construct
begain
mid
Construct
destruct
mid
1
end
destruct
In my expectation, constructors and destructors will only be called once. But what's puzzling is that according to the output, they were called twice.
I've googled this question, and many of the answers have not explained why the constructor is called when the object is defined, and why the destructor is called immediately after the constructor is called
Your program runs as follows:
The constructor is called for the global object test myclassone;.
main() is called.
begain and mid are printed.
The constructor is called for the temporal object test(1,1,1).
The temporal object is assigned to the global object.
The destructor is called for the temporal object test(1,1,1).
mid is printed.
myclassone.show() is called.
end is printed.
Return from main().
The destructor is called for the global object test myclassone;
Therefore the constructor and destuctor are called once for each objects and called twice in total.
In the following code, the vector loses all its content before calling the print method.
I am assuming the destructor is called before the print statement.
Could anyone let me know why a destructor is called before the object is going out of scope.
#include<iostream>
#include <vector>
using namespace std;
class test {
private:
vector<int> distance;
public:
test();
void print();
};
void test::print() {
cout << "In Print";
for (auto itr = distance.begin(); itr != distance.end(); ++itr)
cout << *itr << "\n";
}
test::test() {
std::vector<int>distance(100, 1);
}
int main()
{
cout << "executing main \n";
test t;
t.print();
cin.get();
return 0;
}
test::test() {
std::vector<int>distance(100, 1);
}
This will create a new vector local to the constructor, that will be destroyed as soon as the constructor finishes.
To initialize the vector in your class you should use initializer list.
test::test() : distance(100,1) {}
Edit
Another option is to initialize the vector in the class definition.
#include<iostream>
#include <vector>
using namespace std;
class test {
private:
vector<int> distance{5, 7, 9, 12};
public:
test();
void print();
};
void test::print() {
cout << "In Print";
for (auto itr = distance.begin(); itr != distance.end(); ++itr)
cout << *itr << "\n";
}
int main()
{
cout << "executing main \n";
test t;
t.print();
cin.get();
return 0;
}
SOLUTION
The correct way to initialize the member vector in the constructor is:
test::test()
: distance(100, 1) // initializes member vector with 100 ones, but
// you may use any vector constructor here
{
}
This will also work:
test::test()
: distance() // this line is implicit if you don't add it
{
for (auto i = 0; i < 100; ++i) {
distance.push_back(1); // appends 1 to the member distance
}
}
but it is not desirable since it is less efficient because you create and initialize a default empty vector, and then you initialize it again in the body of the constructor. However, depending on what you need to initialize the vector with, it may make sense to do it in the body of the constructor, if the values require calculating, for instance.
For a good reference of std::vector<>, including its constructors, see cppreference.com. This vector tutorial that I wrote may also be of use: C++ std::vector for post-beginners.
YOUR PROBLEM
Your constructor is creating a new and different vector with the same name in its body. Then, when the destructor is finished, the new vector initialized there goes out of scope, and it is destroyed:
test::test()
{
vector<int> distance(100, 1); // Creates a new vector with the same
// name as your member variable.
} // end of constructor scope; the vector created here is destroyed
The constructor above is equivalent to:
test::test()
: distance() // default initialization of member distance
{
vector<int> distance(100, 1); // Creates a new different vector with the
// same name as your member variable.
} // end of constructor scope; the new vector created is destroyed
Destructors are called in reverse order of object creation in C++ but I do not understand why it is not maintained for array of objects.
#include <iostream>
using namespace std;
class test {
int nmbr;
static int c;
public:
test(int j)
{
cout<<"constructor is called for object no :"<<j<<endl;
nmbr=j;
};
~test()
{
c++;
cout<<"destructor is called for object no :"<<c<<endl;
};
};
int test::c=0;
int main()
{
test ob[]={test(1),test(2),test(3)};
return 0;
}
The above program outputs
constructor is called for object no :1
constructor is called for object no :2
constructor is called for object no :3
destructor is called for object no :1
destructor is called for object no :2
destructor is called for object no :3
But why destructors are not called in reverse order?
It is called in reverse order. You are printing variable c. Look at my comment in this program - "I changed here". You were printing a count variable where you should have printed the object that was being destroyed.
You can read more here:
https://isocpp.org/wiki/faq/dtors#order-dtors-for-arrays
#include <iostream>
using namespace std;
class test {
int nmbr;
static int c;
public:
test(int j)
{
cout<<"constructor is called for object no :"<<j<<endl;
nmbr=j;
};
~test()
{
c++;
// I changed here
cout<<"destructor is called for object no :"<<nmbr<<endl;
};
};
int test::c=0;
int main()
{
test ob[]={test(1),test(2),test(3)};
return 0;
}
They are, the error is with your test. In calling the destructor you are accessing a number you are setting yourself. Change the destructor output to show the actual value within the class and you will see for yourself
cout<<"destructor is called for object no :"<<nmbr<<endl;
The destructors are called in reverse order of the constructor calls.
It is your test that is producing and printing values incorrectly.
Try this code, and you will see the expected results.
#include <iostream>
class test {
int this_instance;
static int number_of_instances;
public:
test() : this_instance(number_of_instances++)
{
std::cout << "constructor invoked for object :"<< this_instance << '\n';
};
~test()
{
std::cout << "destructor invoked for object :" << this_instance << '\n';
};
};
int test::number_of_instances = 0;
int main()
{
test first_batch[4];
return 0;
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
file scope and static floats
What are static variables?
Here is a code from a book.
class X
{
int i;
public:
X(int ii = 0) : i(ii) {cout<<i<<endl;} // Default
~X() { cout << "X::~X()" << endl; }
};
void f()
{
static X x1(47);
static X x2; // Default constructor required
}
int main()
{
f();
return 0;
}
My question is why would I like to declare an object as static like in function f()? What would happen if I did not declare x1 and x2 as static?
For this code it makes no difference to the observable behavior of the program.
Change main to call f twice instead of only once, and observe the difference -- if the variables are static then only one pair of X objects is ever created (the first time f is called), whereas if they're not static then one pair of objects is created per call.
Alternatively, change main to print something after calling f. Then observe that with static, the X objects are destroyed after main prints (the static objects live until the end of the program), whereas without static the objects are destroyed before main prints (automatic objects only live until exit from their scope, in this case the function f).
The first time the function f() is hit the statics will be initialized (lazy loading). Had they not been declared static then they would be local variables and recreated every time you called function f().
All calls to f() will result in using the same x1 and x2.
The difference between
int f()
{
int i = 0;
++i;
return i;
}
int f2()
{
static int i = 0;
++i;
return i;
}
int main()
{
for (int i = 0; i < 10; ++i) { cout << f1() << ' ' << f2() << endl; }
}
Is that f1 will always make a new local variable i and set it to zero then increment it, while f2 will create a static local variable i and initialize it to zero once and then each call it increments it from the previous call value.
Here is some code to test what does a static object within a function mean:
#include <iostream>
using namespace std;
class A {
public:
void increase() {
static int b = 0;
b++;
cout << "A::increase: " << b << endl;
}
};
int main() {
A a;
a.increase();
a.increase();
a.increase();
return 0;
}
And the output is:
A::increase: 1
A::increase: 2
A::increase: 3
Notice the value of b is kept between function calls? Here is the example on ideone so that you can play with it.
class A
{
int id;
static int count;
public:
A()
{
count++;
id = count;
cout << "constructor called " << id << endl;
}
~A()
{
//count -=2; /*Keypoint is here. */
/*Uncomment it later. But result doesn't change*/
cout << "destructor called " << id << endl;
}
};
int A::count = 0;
int main()
{
A a[2];
return 0;
}
The output is
constructor called 1
constructor called 2
destructor called 2
destructor called 1
The question is:
even if you uncomment the //count -=2;
the result is still the same.
Does that mean that if the constructor increments the static member by 1,then the destructor must decrement it exactly by 1 also, and you can't change the behaviour of it?
Nothing accesses count after the first destructor is invoked. The destructor does exactly what you code it to do, either modifying count or not. But you won't see the effect unless you access count in some way.