Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

A question related to Copy Constructor

Posted on 2003-11-17
4
Medium Priority
?
604 Views
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() ;
      }      
    system("PAUSE");      
    return 0;
}


Now, the output above prints
Constructor
1
Before f()
1
Destructor
0
After f()
0
Destructor
-1
Destructor
-2


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

Amit
0
Comment
Question by:Sys_Prog
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
4 Comments
 
LVL 11

Accepted Solution

by:
bcladd earned 200 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,
-bcl
0
 
LVL 10

Author Comment

by:Sys_Prog
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

Amit
0
 
LVL 11

Expert Comment

by:bcladd
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 (gamedev.net 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
0
 
LVL 9

Assisted Solution

by:_ys_
_ys_ earned 200 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.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

636 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