A question related to Copy Constructor

Posted on 2003-11-17
Last Modified: 2008-03-03
I was just going thru Thinking in C++ and came across a confusing issue.
The below code demonstrates that

class A {
        static int i ;
public :
      A () {
        i++ ;
        cout << "Constructor" << endl ;
        j = 0 ;
       ~A () {
         i-- ;
         cout << "Destructor" << endl ;
         print ( ) ;
       static void print ( ) {
               cout << i << endl ;

A f (A temp ) {
       A::print ( ) ;
       return temp ;

int A::i = 0 ;

int main(int argc, char *argv[]) {

            A a1 ;
            A::print() ;
            cout << "Before f () " << endl ;
            A a2 = f ( a1 ) ;
            cout << "After f () " << endl ;
            A::print() ;
    return 0;

Now, the output above prints
Before f()
After f()

The book explains the above output in the following way

After a1 is created, the object count is one, which is fine. But after the call to f( ) you would expect to have an object count of two, because a2 is now in scope as well. Instead, the count is zero, which indicates something has gone horribly wrong. This is confirmed by the fact that the two destructors at the end make the object count go negative, something that should never happen.

Look at the point inside f( ), which occurs after the argument is passed by value. This means the original object a1 exists outside the function frame, and there’s an additional object inside the function frame, which is the copy that has been passed by value. However, the argument has been passed using C’s primitive notion of bitcopying, whereas the C++ HowMany class requires true initialization to maintain its integrity, so the default bitcopy fails to produce the desired effect.

When the local object goes out of scope at the end of the call to f( ), the destructor is called, which decrements objectCount, so outside the function, objectCount is zero. The creation of a2 is also performed using a bitcopy, so the constructor isn’t called there either, and when a1 and a2 go out of scope, their destructors cause
the negative values of objectCount.

My question========
I didn't get the fact that when u say that copy is happening as per C-style bit-copying, thus the constructor does not get called. OK, but then why does the destrcutor for that particular object gets called.....?? Also, is this not a loophole on part of C++, though I know that the solution to the above problem is using Copy-Constructors

Your comments are welcome

Thanks in advance

Question by:Sys_Prog
  • 2
LVL 11

Accepted Solution

bcladd earned 50 total points
ID: 9763037
Actually, a copy constructor IS being called. Granted, you didn't write one, but the compiler provided one when one was required but not provided. The ACTIVITY of the provided copy constructor was to call memcpy (copy the memory occupied by the original into the copy). So, though the effect is a simple struct assignment, a C++ copy constructor was called.

This behavior is often all you need (no static variables, no dynamic memory allocation). You can also get away without defining a default constructor (one is provided for you free of charge by the compiler if it is used) that will simply call default constructors for parent classes and class members; destructors are also provided if not defined.

Note that the three default implementations are public which may not be what you want. Thus to create a singleton (see a design patterns reference if necessary) the constructor and copy constructor are defined as protected and the body of the copy constructor is typically not provided (it is a conceptual error to make a copy of a singleton, something there should be only one of).

Hope this helps,
LVL 10

Author Comment

ID: 9763159
Hi bcladd,

I got the first two para's of whatever u said, could u please eloborate on the third para

Also, one more question regarding whatever u exaplined in the 1st 2 para's

As per my understanding OR whatever I have read of copy-constructor, a copy-constructor should  always have a argument of the same type by REFERNCE. But when the compiler does provide that copy constructor internally, does it consider this fact, I guess it would be considering

Thanks in advance

LVL 11

Expert Comment

ID: 9763260
(1) Singleton is a design pattern where you only want exactly one of an object instantiated, never two. Consider an object representing the error logging system in a game engine ( has a series of articles on something called Enginuity that I am reading; example from part 2 of the article). You don't want two error loggers because each would have to have control of the same open files. So we don't want anyone copying our Elog object. The best way to accomplish that is to hide the copy constructor; the compiler will then not permit anyone to pass Elog by value or otherwise copy it. We also don't want anyone to create a new one so we hide the default constructor.

Typically, to make it so that a client of an object cannot do something we just don't define a function that does "that". Doesn't work for copy or default constructors because the compiler will provide one silently when it is called.

(2) The provided copy constructor looks something like this (this is a simplified approximation):

Copyless::Copyless(const Copyless & original) {
    memcpy(this, &original, sizeof(*this);

Hope this helps, -bcl

Assisted Solution

_ys_ earned 50 total points
ID: 9765369
>but then why does the destrcutor for that particular object gets called.....??
Don't think bcladd covered this part.

By now you should be accepting of the fact that the compiler has synthesised a copy constructor on your behalf, and called it appropriately. And because you didn't write it, i++ never happened.

I'm also hoping you understand the concept of constructor overloading - and that you can have multiple constructors defined.

But, you can only ever have one (and only one) destructor. It cannot be overloaded, and it does not return a value either. Incidentally you _must_ have a destructor. If you don't provide one the compiler synthesises this for you as well.

As you can only have one, it will be called. Thus i-- will get executed. The fact that it used the synthesised copy constructor to create the instance is irrelevant. It still needs to invoke a destructor.

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now