Thread: Passing Objects, Constructors, Pointers, References, Values ???

  1. #16
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Code:
    class MyClass
    {
    public:
    	MyClass() { }
    	MyClass(const MyClass& rMyClass) { cout << "Copy constructor\n"; } // Copy constructor
    	MyClass& operator = (const MyClass& rMyClass) { cout << "Assignment operator\n"; return *this; }
    };
    
    void Help2(MyClass m)
    {
    }
    
    int main()
    {
    	MyClass a;
    	MyClass b;
    	a = b; // Invokes operator =
    	Help2(a); // Invokes copy constructor
    }
    There's a better example, I think.
    Last edited by Elysia; 12-14-2007 at 02:50 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  2. #17
    Registered User
    Join Date
    Aug 2007
    Posts
    66
    I tried the following source code:

    Code:
    #include <iostream>
    
    using namespace std;
    class MyClass
    {
          public:
                 MyClass() { cout <<"----------MyClass Constructor..."<<endl;}   // constructor
                 MyClass(MyClass&) { cout <<"+++++++MyClass Copy Constructor..." << endl;}  // copy constructor
                 ~MyClass() { cout <<"=======MyClass Destructor..." << endl;}   // destructor
    };
    
    MyClass Function1 ()
    {
            cout << endl << endl << "Ok, boss. This is inside the function1" << endl;
            cout << "Nothing is returned" << endl;
            
    }
    
    
    
    int main()
    {
    
        cout << "I am going to create MyClass MyObject" << endl;
        MyClass MyObject;
        cout << "MyObject has just created" << endl << endl;
        cout << endl << "I am going to call the MyClass Function1 into the next line." << endl;
        Function1();
        cout << endl << endl << endl << "We are back to main." << endl;
        cout << "Zero is going to returned and exit main.." << endl;
        
        return 0;
    }
    The Output is:
    Code:
    I am going to create MyClass MyObject
    ----------MyClass Constructor...
    MyClass MyObject has just created
    
    I am going to call the MyClass Function1 into the next line.
    
    Ok, boss. This is inside the function1
    Nothing is returned
    =======MyClass Destructor...
    
    
    We are back to main.
    Zero is going to returned and exit main..
    =======MyClass Destructor...
    Analysis:
    When I create a object, the constructor of the class is called.
    When I call a object-oriented function without any arguments, none constructor is called.
    When I exit from the this function, without returning a value or something, the destructor of the class is called.
    When I eventually exit from int main() function, the destructor of the class is called once again.

    So,
    1) when you create an object, the constructor is called.
    2) when you exit from any type (int, char, class, etc) of function, the destructor is called.Even if you haven't create an object in order to -in some way- activate the object oriented engine, the destructor is called.



    So let's go further to my source code example number two.

    Code:
    #include <iostream>
    
    using namespace std;
    class MyClass
    {
          public:
                 MyClass() { cout <<"----------MyClass Constructor..."<<endl;}   // constructor
                 MyClass(MyClass&) { cout <<"+++++++MyClass Copy Constructor..." << endl;}  // copy constructor
                 ~MyClass() { cout <<"=======MyClass Destructor..." << endl;}   // destructor
    };
    
    MyClass Function1 (MyClass MyObject)
    {
            cout << endl << endl << "Ok, boss. This is inside the function1" << endl;
            cout << "Nothing is returned" << endl;
            
    }
    
    
    
    int main()
    {
        cout << "I am going to create MyClass MyObject" << endl;
        MyClass MyObject;
        cout << "MyObject has just created" << endl << endl;
        cout << endl << "I am going to call the MyClass Function1 into the next line with an Object as an arguement." << endl;
        Function1(MyObject);
        cout << endl << endl << "We are back to main." << endl;
    
        cout << "Zero is going to returned and exit main.." << endl;
       
        return 0;
    }
    Output
    Code:
    I am going to create MyClass MyObject
    ----------MyClass Constructor...
    MyClass MyObject has just created
    
    I am going to call the MyClass Function1 into the next line with an Object as an arguement.
    +++++++MyClass Copy Constructor...
    
    Ok, boss. This is inside the function1
    Nothing is returned
    =======MyClass Destructor...
    =======MyClass Destructor...
    
    We are back to main.
    Zero is going to returned and exit main..
    =======MyClass Destructor...
    Analysis:
    When you call a class function with a class object as an argument, then the Copy Constructor is called. This is becauce
    (by calling this function) there is another temporary copy of this class object into the stack.
    So the copy constructor is called each time a temporary copy of the object is put on the stack.

    Then when, the function exits, this temporary copy of the objects is destroyed, so the object's destructor is called.
    Then the function exits, and the destructor is recalled.

    Eventually the main() exits too, and the destructor is called for once last time.



    No, let's delve it :P
    Source Code Example Number 3

    Code:
    #include <iostream>
    
    using namespace std;
    class MyClass
    {
          public:
                 MyClass() { cout <<"----------MyClass Constructor..."<<endl;}   // constructor
                 MyClass(MyClass&) { cout <<"+++++++MyClass Copy Constructor..." << endl;}  // copy constructor
                 ~MyClass() { cout <<"=======MyClass Destructor..." << endl;}   // destructor
    };
    
    MyClass Function1 (MyClass MyObject)
    {
            cout << endl << endl << "Ok, boss. This is inside the function1" << endl;
            cout << "The copy of the Object is returned" << endl;
            return MyObject;
            
    }
    
    
    
    int main()
    {
    
        cout << "I am going to create MyClass MyObject" << endl;
        MyClass MyObject;
        cout << "MyObject has just created" << endl << endl;
        cout << endl << "I am going to call the MyClass Function1 into the next line." << endl;
        Function1(MyObject);
        cout << endl << endl << "We are back to main." << endl;
        
        cout << "Zero is going to returned and exit main.." << endl;
    
       
        return 0;
    }
    Output:
    Code:
    I am going to create MyClass MyObject
    ----------MyClass Constructor...
    MyClass MyObject has just created
    
    I am going to call the MyClass Function1 into the next line with an Object as an arguement.
    +++++++MyClass Copy Constructor...
    
    Ok, boss. This is inside the function1
    The copy of the Object is returned
    +++++++MyClass Copy Constructor...
    =======MyClass Destructor...
    =======MyClass Destructor...
    
    We are back to main.
    Zero is going to returned and exit main..
    =======MyClass Destructor...
    Analysis:
    The output here is the same as the above, but...there are some details. This time, the function returns the object.
    To make this happen, a copy of that object is re-made (the second) is the stack, so the copy constructor is called.



    Am I right guys ?

  3. #18
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by BlackSlash12 View Post
    Am I right guys ?
    Not quite.

    For example 1:
    Undefined behavior because you have declared that your function returns an object, but you never return one. You must return an a value (or object) of the specified type that you declared in a function.

    Example two:
    Undefined behavior.

    Example 3:
    Main creates a new object. Calls constructor.
    Main calls function. New object is constructed. Copy constructor is invoked.
    An object is being returned, so a new object is constructed. Copy constructor is invoked to copy argument into temporary object.
    Temporary object & argument are both destructed. Both destructors are called.
    Back in main, the class is destructed when it ends.

    For two, you also seem confused that the destructor will be called twice, but since you never return an object, there's no temporary object to destruct. So it would get called only once, if the code should compile, that is.
    In C++, you must return a value if your function specifies that it returns one.
    Last edited by Elysia; 12-15-2007 at 04:14 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #19
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Your first example is undefined behavior. Your function specifies a return value but doesn't actually return one. You can safely avoid any analysis attempt because the code is wrong and the effect you see is likely just a side effect of how the compiler implements proper code.

    Your second example has the same problem.

    The analysis on the third example is fine. Note that the output is slightly different than in example two. In the second example, there are only two constructor calls. In the third example, the only valid one, there are the same number of constructor and destructor calls.

  5. #20
    Registered User
    Join Date
    Aug 2007
    Posts
    66
    Well I fixed the first example:

    Code:
    #include <iostream>
    
    using namespace std;
    class MyClass
    {
          public:
                 MyClass() { cout <<"----------MyClass Constructor..."<<endl;}   // constructor
                 MyClass(MyClass&) { cout <<"+++++++MyClass Copy Constructor..." << endl;}  // copy constructor
                 ~MyClass() { cout <<"=======MyClass Destructor..." << endl;}   // destructor
    };
    
    void Function1 (void)
    {
            cout << endl << endl << "Ok, boss. This is inside the function1" << endl;
            cout << "Nothing returned" << endl;
            
            
    }
    
    
    
    int main()
    {
    
        cout << "I am going to create MyClass MyObject" << endl;
        MyClass MyObject;
        cout << "MyObject has just created" << endl << endl;
        cout << endl << "I am going to call the MyClass Function1 into the next line." << endl;
        Function1();
        cout << endl << endl << "We are back to main." << endl;
        
        cout << "Zero is going to returned and exit main.." << endl;
    
       
        return 0;
    }
    Compiled this time, sorry ....
    Code:
    I am going to create MyClass MyObject
    ----------MyClass Constructor...
    MyClass MyObject has just created
    
    I am going to call the MyClass Function1 into the next line with an Object as an arguement.
    
    
    Ok, boss. This is inside the function1
    Nothing is returned
    
    
    We are back to main.
    Zero is going to returned and exit main..
    =======MyClass Destructor...
    The example 3, I compiled it and I got --> 2 copy constructors and 3 destructors. Is this normal ? I think yes. The 2 copy constructors = 2 destructors + 1 destructor for main.

    Elysia there is no other constructor. Just one an the start.

  6. #21
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Well, your current example is fine, and you should get 1 constructor and one destructor.
    Last edited by Elysia; 12-15-2007 at 04:14 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #22
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> Is this normal ? I think yes.
    Yes. A copy constructor is still a constructor. There should be an equal number of constructors and destructors.

  8. #23
    Registered User
    Join Date
    Aug 2007
    Posts
    66
    another way to avoid 2Copy Constructors and its 2Destructors:

    Code:
    #include <iostream>
    
    using namespace std;
    class MyClass
    {
          public:
                 MyClass() { cout <<"----------MyClass Constructor..."<<endl;}   // constructor
                 MyClass(MyClass&) { cout <<"+++++++MyClass Copy Constructor..." << endl;}  // copy constructor
                 ~MyClass() { cout <<"=======MyClass Destructor..." << endl;}   // destructor
    };
    
    MyClass *Function1 (MyClass *MyObject)
    {
            cout << endl << endl << "Ok, boss. This is inside the function1" << endl;
            cout << "Return Object" << endl;
            return MyObject;
            
    }
    
    
    
    int main()
    {
    
        cout << "I am going to create MyClass MyObject" << endl;
        MyClass MyObject;
        cout << "MyObject has just created" << endl << endl;
        cout << endl << "I am going to call the MyClass Function1 into the next line." << endl;
        Function1(&MyObject);
        cout << endl << endl << "We are back to main." << endl;
        
        cout << "Zero is going to returned and exit main.." << endl;
    
       
        return 0;
    }

  9. #24
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    There is a big difference between passing by reference (which is what you're doing with the pointer) and passing by value (which is what you were doing before). You can't just change it like that to avoid a copy, because the meaning of the code changes.

    To avoid a copy without changing the meaning of the code, you can usually use a reference to const to ensure that the object doesn't get changed.
    Code:
    const MyClass& Function1 (const MyClass& MyObject);
    If it did get changed, and the function took the object by value, then changing it to a reference or pointer means that the original object is modified instead of the copy. That changes the entire meaning of the function, so you have to make that change only if you want to change the function's effects.

  10. #25
    Registered User
    Join Date
    Aug 2007
    Posts
    66
    Well Daved, you have rights as always. I am reading this C++ book, and it reveals me slowly the secrets. Thanks man and thank all of you guys. I really appreciate your help and guideness.

    Queries solved;
    Topic Closed;

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Returning an Array of Pointers to Objects
    By randomalias in forum C++ Programming
    Replies: 4
    Last Post: 04-29-2006, 02:45 PM
  2. Pointers to objects on the heap
    By foot in forum C++ Programming
    Replies: 3
    Last Post: 07-21-2005, 12:20 PM
  3. pointers in arrays... Declaring objects in a loop.
    By Guest852 in forum C++ Programming
    Replies: 10
    Last Post: 04-05-2005, 06:57 AM
  4. Pointers and references...
    By SushiFugu in forum C++ Programming
    Replies: 6
    Last Post: 12-08-2001, 04:21 PM
  5. Passing objects
    By Wiggin in forum C++ Programming
    Replies: 1
    Last Post: 10-17-2001, 08:00 AM