Re: A question about destructor
"Lorry Astra" <LorryAstra@discussions.microsoft.com> wrote in message
news:F0997FD3-6445-4A2D-A768-90DFD1501B0D@microsoft.com...
Hello everyone, I learned a code sample from a book.
#include <fstream>
#include <string>
using namespace std;
class HowMany {
static int objectCount;
public:
HowMany() { objectCount++; }
static void print(const string& msg = "")
{
if(msg.size()!=0)
cout << msg << ":" << "objectCount = " << objectCount << endl;
}
~HowMany()
{
objectCount--;
print("~HowMany()");
}
};
int HowMany::objectCount = 0;
HowMany f(HowMany x)
{
x.print("x argument inside f()");
return x;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
HowMany h;
HowMany::print("after construction of h");
HowMany h2 = f(h);
HowMany::print("after call to f()");
}
return nRetCode;
}
I'm a C++ beginner,and now I have three questions:
1. Why the destructor will be called at the end of "HowMany f(HowMany x) "
function, I think the "x" object is not a new object, it's an object
passed
from outside of this function.
You are wrong about that. With the function
HowMany f(HowMany x)
x is "passed by value". This means that the function makes a local copy of
the HowMany object that is passed to it as an argument. If you don't want a
copy, then you "pass by reference". The function signature then looks like:
HowMany f(HowMany & x)
2. Why the desturctor will be called twice at the end of main function.
Because at that point there are two local HowMany objects, h and h2, that go
out of scope.
3. It is not related with the code sample. I wonder CLS is really useful
to
C++? Is it better than MFC?
I have no idea what CLS is so will pass on question 3.
For questions 1 and 2, you need to track what happens more closely. First
you need to add a user-defined copy constructor, since a compiler-generated
copy constructor is being invoked with your existing code and you aren't
tracking it.
Second you need to output to screen whenever either constructor is called,
so you can see that is happening. Try this code:
class HowMany
{
static int objectCount;
public:
HowMany()
{
objectCount++;
print("Inside default constructor ");
}
HowMany(const HowMany &rhs)
{
objectCount++;
print("Inside copy constructor ");
}
~HowMany()
{
objectCount--;
print("Inside destructor ");
}
static void print(const string& msg = "")
{
if(msg.size()!=0)
cout << msg << ":" << "objectCount = " << objectCount << endl;
}
};
int HowMany::objectCount = 0;
HowMany f(HowMany x)
{
x.print("Inside f() function ");
return x;
}
int main()
{
int nRetCode = 0;
HowMany h;
HowMany::print("\nAfter declaration of h");
cout << "About to call f(h) and assign to h2\n" << endl;
HowMany h2 = f(h);
HowMany::print("\nAfter call to f()");
return nRetCode;
}
Now change the definition of f to
HowMany f(HowMany & x)
{
x.print("Inside f() function ");
return x;
}
and see what difference it makes.
--
John Carson