none
Passing object mCB to a Method of object mCA: Is this passing by reference?

    Question

  • I'm sure I'm not wording this question properly but maybe some helpful soul can understand what I'm trying to ask...

    Below is a simplification of some code...

    - Note how the object mCB is passed by main()'s LINE X to the mCA.Execute method
    - and how the mCA.Execute Method's LINE Y "receives" it as an address of the object

    And, the code works...
    - the address of the object as displayed in main() is the same as displayed in mCA method...
    - And you can still use the objects method from within the mCA method...

    The Questions:

    1 - This is considered passing an 'object' by reference... right? (somehow I always think of pointers when passing by reference)

    2 - Is this the proper way to pass and object to another objects method or to a function?

    thanks for any help.

    class myClassA;
    class myClassB;
    
    class myClassA
    {
    public:
    	bool Execute(char* CmdStr, myClassB& Tbl);
    };
    
    class myClassB
    {
    public:
    	void mcbTalk(){cout<<"mcb is talking"<<endl;}
    };
    
    bool myClassA::Execute(char* SomeStr, myClassB& xyz) //LINE Y - receive objects address
    {
    	cout<<"xyz Objects address: "<<&xyz<<endl; //it's the same address
    	xyz.mcbTalk(); //we can reach the methods
    	getchar();
    	return 0;
    }
    
    int main()
    {
    	cout<<"mainTestStuff2 main"<<endl;
    	myClassA mCA;	//create instance
    	myClassB mCB;	//create instance
    
    	cout<<"mCB objects address: " << &mCB<<endl;
    	mCA.Execute("DoDa",mCB);  // LINE X - pass the object
    
    	getchar();
    	return 0;
    }
    

    Saturday, May 12, 2012 4:05 PM

Answers

  • Mel_3 wrote:

    - Note how the object mCB is passed by main()'s LINE X to the  mCA.Execute method
    - and how the mCA.Execute Method's LINE Y "receives" it as an address  of the object

    myClassB& is "a reference to type myClassB". The ampersand & in this  context is different from its use as address-of operator.

    And, the code works...
    - the address of the object as displayed in main() is the same as  displayed in mCA method...

    A reference is an alias (a different name) for the same underlying  object. So you get the same address regardless of which name you request  it from.

    1 - This is considered passing an 'object' by reference... right?

    Yes.

    2 - Is this the proper way to pass and object to another objects  method or to a function?

    It is one of several possible ways. Different approaches could be  reasonably chosen for different situations.


    Igor Tandetnik

    • Proposed as answer by Helen Zhao Monday, May 14, 2012 7:25 AM
    • Marked as answer by Helen Zhao Monday, May 21, 2012 4:29 AM
    Saturday, May 12, 2012 5:04 PM
  • Effectively the difference between passing by reference and passing by value is whether you want to keep the original variable the same, or change it.

    If you think about it, it is called a reference, so it should be easy to tell that it passing by reference. For example

    void myfun(int &a );

    a is a reference to a value of type int. So if you call this like

    myfun(someintvariable);

    then a is a reference to someintvariable. So is it that confusing that this is passing by reference?

    But truthfully none of that matters. What matters is only whether the value changes or not. If the result is the original variable changes then it is passing by reference, otherwise it is passing by value. You seem to be too concerned with the how.

    If you really want to focus on the wrong things, ask yourself, does it have to have a * to be seen as a pointer? What is there to say that the compiler writers can't treat & in a similar way to *? You see, on the machine level, a reference is really syntactic sugar around a pointer. So & is like * const (ie, once you assign the value to the reference, you can't change it) and when you are using it, the compiler automatically dereferences it.


    This is a signature

    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Do you want Visual Studio 11 Express to be freely installable on Windows 7 and able to write regular C++ applications? Please vote for this.


    • Edited by Crescens2k Saturday, May 12, 2012 9:30 PM
    • Proposed as answer by Helen Zhao Monday, May 14, 2012 7:25 AM
    • Marked as answer by Helen Zhao Monday, May 21, 2012 4:29 AM
    Saturday, May 12, 2012 9:29 PM
  • myFunc1 (int x,int y) {x=5;y=2;} //pass by value
    myFunc2(int* x,int* y){x=5;y=2;} //pass by ref using Pointers
    myFunc3(int& x, int& y){y=5;y=2;} //pass by ref using References (Aliases)
     
    int x=3;int y = 1; myFunc1(x,y); //call myFunc1 and pass by value
    x=3;y = 1; myFunc2(int &x,int &y); //call myFunc2 and pass by ref using pointers
    x=3;y = 1; myFunc3(int x,int y); //call myFunc3 and pass by ref using References (Aliases)
    I think you meant
     
    myFunc1 (int x, int y) {x=5; y=2;} //pass by value
    myFunc2(int* x, int* y){*x=5; *y=2;} //pass by ref using Pointers
    myFunc3(int& x, int& y){x=5; y=2;} //pass by ref using References (Aliases)
     
    int x = 3; int y = 1; myFunc1(x,y);
    x = 3; y = 1; myFunc2(&x, &y);
    x = 3; y = 1; myFunc3(x, y);
     

    David Wilkinson | Visual C++ MVP
    • Edited by davewilkMVP Monday, May 14, 2012 8:16 PM additional correction
    • Marked as answer by Helen Zhao Monday, May 21, 2012 4:30 AM
    Monday, May 14, 2012 7:13 PM

All replies

  • Mel_3 wrote:

    - Note how the object mCB is passed by main()'s LINE X to the  mCA.Execute method
    - and how the mCA.Execute Method's LINE Y "receives" it as an address  of the object

    myClassB& is "a reference to type myClassB". The ampersand & in this  context is different from its use as address-of operator.

    And, the code works...
    - the address of the object as displayed in main() is the same as  displayed in mCA method...

    A reference is an alias (a different name) for the same underlying  object. So you get the same address regardless of which name you request  it from.

    1 - This is considered passing an 'object' by reference... right?

    Yes.

    2 - Is this the proper way to pass and object to another objects  method or to a function?

    It is one of several possible ways. Different approaches could be  reasonably chosen for different situations.


    Igor Tandetnik

    • Proposed as answer by Helen Zhao Monday, May 14, 2012 7:25 AM
    • Marked as answer by Helen Zhao Monday, May 21, 2012 4:29 AM
    Saturday, May 12, 2012 5:04 PM
  • Well then I'm confused since the object does not seem to be passed as a pointer (no '*' symbol)

    When you simply put the name of an object in a function call as an argument...

    then have the actual function effectively rename it (create an alias for it) for its use within that function...

    How is that passing by 'reference" ??

    I can see that it is apparently doing as you say and passing the object by reference... since I put a property into myClassB
    int myB;
    then in myClassA::Execute I changed the value via...
    xyz.myB = 12;
    then in main(), after the call to Execute... I displayed the value of xyz.myB and it was indeed changed.

    But I guess I don't understand how C++ knows we are passing the object by reference... and not by value.

    thanks for the help.

    Saturday, May 12, 2012 8:12 PM
  • Effectively the difference between passing by reference and passing by value is whether you want to keep the original variable the same, or change it.

    If you think about it, it is called a reference, so it should be easy to tell that it passing by reference. For example

    void myfun(int &a );

    a is a reference to a value of type int. So if you call this like

    myfun(someintvariable);

    then a is a reference to someintvariable. So is it that confusing that this is passing by reference?

    But truthfully none of that matters. What matters is only whether the value changes or not. If the result is the original variable changes then it is passing by reference, otherwise it is passing by value. You seem to be too concerned with the how.

    If you really want to focus on the wrong things, ask yourself, does it have to have a * to be seen as a pointer? What is there to say that the compiler writers can't treat & in a similar way to *? You see, on the machine level, a reference is really syntactic sugar around a pointer. So & is like * const (ie, once you assign the value to the reference, you can't change it) and when you are using it, the compiler automatically dereferences it.


    This is a signature

    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Do you want Visual Studio 11 Express to be freely installable on Windows 7 and able to write regular C++ applications? Please vote for this.


    • Edited by Crescens2k Saturday, May 12, 2012 9:30 PM
    • Proposed as answer by Helen Zhao Monday, May 14, 2012 7:25 AM
    • Marked as answer by Helen Zhao Monday, May 21, 2012 4:29 AM
    Saturday, May 12, 2012 9:29 PM
  • But I guess I don't understand how C++ knows we are passing the object by reference... and not by value.
    Because the function is declared as
     
    bool Execute(char* CmdStr, myClassB& Tbl);
     
    not
     
    bool Execute(char* CmdStr, myClassB Tbl);
     
    If you wish you may think of a C++ reference as a pointer that (a) does not need to be dereferenced and (b) cannot be NULL (i.e. must point to something).
     
    Note that pass by pointer in C or C++ is not pass by reference; the pointer itself is passed by value. It's just that by dereferencing the pointer you can simulate pass by reference.
     

    David Wilkinson | Visual C++ MVP
    Saturday, May 12, 2012 9:38 PM
  • Mel_3 wrote:

    Well then I'm confused since the object does not seem to be passed as  a pointer (no '*' symbol)

    Why is that a problem?

    How is that passing by 'reference" ??

    By definition. For any type T, type T& is called "reference to T". In  your case, the function argument is of type myClassB&, that is, a  reference to myClassB. Thus, the function takes a reference as its  parameter - in other words, the parameter is passed by reference.

    But I guess I don't understand how C++ knows we are passing the object  by reference... and not by value.

    A function taking its parameter by value would be declared with an  argument of type myClassB rather than myClassB&.


    Igor Tandetnik

    Saturday, May 12, 2012 10:24 PM
  • Thanks for the help Guys.

    As a point of information I understood the difference in passing by value vs passing by reference.

    What I was unclear on was passing by reference using Pointers - vs - passing by reference using References (Aliases)

    myFunc1 (int x,int y) {x=5;y=2;} //pass by value
    myFunc2(int* x,int* y){x=5;y=2;} //pass by ref using Pointers
    myFunc3(int& x, int& y){y=5;y=2;} //pass by ref using References (Aliases)

    int x=3;int y = 1; myFunc1(x,y); //call myFunc1 and pass by value
    x=3;y = 1; myFunc2(int &x,int &y); //call myFunc2 and pass by ref using pointers
    x=3;y = 1; myFunc3(int x,int y); //call myFunc3 and pass by ref using References (Aliases)

    and of course you can display the values before calling any of the functions, during the functions and after returning from any of the functions to see that passing by value does not allow the function to access the variables in main... while passing by reference does...

    And, of course, passing by reference using References (Aliases) seems a lot more simple to code as you don't have to dereference the variables in the function)

    But here is a question: Is there a time you should (or must) pass by reference using 'pointers' as opposed to passing by reference using 'references' (or 'aliases') ? It sure seems easier to always pass by reference using References/Aliases.

    Thanks again for the help.

    Monday, May 14, 2012 5:24 PM
  • References cannot be set to NULL.  There are certainly times when it is convenient to pass a pointer parameter that is sometimes NULL. The Win API has lots of such cases: Optional arguments.

    Monday, May 14, 2012 5:36 PM
  • myFunc1 (int x,int y) {x=5;y=2;} //pass by value
    myFunc2(int* x,int* y){x=5;y=2;} //pass by ref using Pointers
    myFunc3(int& x, int& y){y=5;y=2;} //pass by ref using References (Aliases)
     
    int x=3;int y = 1; myFunc1(x,y); //call myFunc1 and pass by value
    x=3;y = 1; myFunc2(int &x,int &y); //call myFunc2 and pass by ref using pointers
    x=3;y = 1; myFunc3(int x,int y); //call myFunc3 and pass by ref using References (Aliases)
    I think you meant
     
    myFunc1 (int x, int y) {x=5; y=2;} //pass by value
    myFunc2(int* x, int* y){*x=5; *y=2;} //pass by ref using Pointers
    myFunc3(int& x, int& y){x=5; y=2;} //pass by ref using References (Aliases)
     
    int x = 3; int y = 1; myFunc1(x,y);
    x = 3; y = 1; myFunc2(&x, &y);
    x = 3; y = 1; myFunc3(x, y);
     

    David Wilkinson | Visual C++ MVP
    • Edited by davewilkMVP Monday, May 14, 2012 8:16 PM additional correction
    • Marked as answer by Helen Zhao Monday, May 21, 2012 4:30 AM
    Monday, May 14, 2012 7:13 PM
  • You are correct David. Keyed it in wrong. Thanks !

    And Scott, thanks for your help, shown below.

    "References cannot be set to NULL.  There are certainly times when it is convenient to pass a pointer parameter that is sometimes NULL. The Win API has lots of such cases: Optional arguments."

    And thanks again to everyone for the help.

    Monday, May 14, 2012 8:44 PM