LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 11-15-2005, 03:08 PM   #1
sepulture
LQ Newbie
 
Registered: Nov 2005
Distribution: RH9
Posts: 8

Rep: Reputation: 0
Question C++ / Passing a variable by reference to a class member function.


I would like to start by showing my appreciation for such a site. Thank you.

I am a n00b coder in C++. I haven't been at it long at all and it is my first language other than HTML. With this background in mind I have written this code: (PLEASE DO NOT RUN THIS, It doesn't end. And please remember I submit this in it's current state. I have edited it since the last compile and fear that it would not compile at this time.)

Code:
#include <iostream>

unsigned short int v_current_time = 0;
unsigned short int v_current_date = 0;
unsigned short int v_current_period = 0;

void f_time_cycle();

class c_entity
{
	public:
		c_entity(unsigned short int v_current_age); // My delima!
		~c_entity();                                                    
		unsigned short int f_return_status();
		void f_adjust_age(unsigned short int v_current_age); // My delima!
		unsigned short int f_return_age();
		bool v_status;
		unsigned short int v_current_age;
};

///////////////////////////////////////////////////////////////////////////////

int main()
{
	std::cout << "NamelessRPG" << std::endl;
	c_entity tester(0);
	bool v_current_status = (tester.f_return_status());
	while(v_current_status != false)
	{
		f_time_cycle();
		tester.f_adjust_age(tester.v_current_age);
		tester.f_return_age();
		std::cout << tester.v_current_age << std::endl;
	}
	return 0;
}

///////////////////////////////////////////////////////////////////////////////

void f_time_cycle()
{
	v_current_time++;
	if(v_current_time == 50000)
	{
		v_current_date++;
		v_current_time = 0;
	}
	if(v_current_date==1000)
	{
		v_current_period++;
		v_current_date = 0;
	}
	std::cout << v_current_time << std::endl;
	std::cout << v_current_date << std::endl;
	std::cout << v_current_period << std::endl;
}

c_entity::c_entity(unsigned short int v_current_age) // My delima!
{
	v_current_age = v_birth_age;
	std::cout << "Its ALIVE!!!" << std::endl;
}

c_entity::~c_entity()
{
	std::cout << "Its DEAD!!!" << std::endl;
}

unsigned short int c_entity::f_return_status()
{
	return (v_status);
}

void c_entity::f_adjust_age(unsigned short int v_current_age) // My delima!
{
	v_current_age++;
}

unsigned short int c_entity::f_return_age()
{
	return (v_current_age);
}
The goal at this stage is to pass the v_current_age variable into appropriate member functions by reference not value. In its current state the routines do not "age" the entity class object as it should. I have fumbled with trying to use references to pass this variable to the right function by reference instead of value but I cannot seem to get it to work.

I realize that many will probably find much wrong with this code ranging from style to poor use of features. Please ignore these for now as I am not ready to delve beyond references at the moment. I would prefer to get a solid grasp on this before moving to something else.

If anyone could show me the proper way to impliment this I would be very appreciative. Thanks in advance for any and all replies.

Last edited by sepulture; 11-15-2005 at 04:17 PM.
 
Old 11-15-2005, 03:49 PM   #2
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 31
You shouldn't have the parameter names the same as your member variable names. Doing so will mask the member variable.

For instance here:
Code:
c_entity::c_entity(unsigned short int v_current_age) // My delima!
{
    // Here you are setting the local v_current_age to v_birth_age, not
    // the member v_current_age. 
    // Additionally, v_birth_age hasn't been initialized so you are setting it 
    // to a garbage variable.
    v_current_age = v_birth_age;  
    std::cout << "Its ALIVE!!!" << std::endl;
}
I think what you want above is actually something like so:
Code:
c_entity::c_entity(unsigned short int current_age) // My delima!
{
    v_current_age = v_birth_age  = current_age;  
    std::cout << "Its ALIVE!!!" << std::endl;
}
Now, this isn't passing by reference like you asked for. I'm not sure that passing by reference is really what you want, but in case it is, here's a simple example of how passing a value by reference is used.

Code:
// Pass by reference using the & operator on the paramter
void Double(int &x)
{
    // Because x is passed by reference when we change it here, it will be
    // changed outside the function as well.
    x = x * 2;
}

int main()
{
    int y = 10;

    // After this call, y will equal 20
    Double(y);

    return 0;
}
NOTE: Please use the [ code] [ /code] tags in the future. It makes your code much more legible.

Last edited by deiussum; 11-15-2005 at 03:50 PM.
 
Old 11-15-2005, 04:03 PM   #3
sepulture
LQ Newbie
 
Registered: Nov 2005
Distribution: RH9
Posts: 8

Original Poster
Rep: Reputation: 0
Please forgive. I had no knowledge of tag use for this type of board.

As I stated I had been editing the code prior to the post, since the last compile. I was aware of the "garbage variable" but I didn't edit it out prior (it was just something I was working on).

As it stands, when I last ran the program, it simply spit out the age of the entity. But I was getting nothing but zero's as the age through each cycle because the effects of the routine were on the copy of the variable being passed by value. I deduced that I would have to pass the variable by reference for it to impact the actual variable and not just a copy. That is when I became stumped and sought advice.

I greatly appreciate your feedback and am now about to "tinker" (for lack of a better term) with it. I shall post my results.

Thank you very much.
 
Old 11-15-2005, 04:16 PM   #4
sepulture
LQ Newbie
 
Registered: Nov 2005
Distribution: RH9
Posts: 8

Original Poster
Rep: Reputation: 0
After my second observation of your reply another question arose. Do I not have to explicitly create a reference to the variable and then pass in the reference or can I just use the address of operator and that serve as a reference to the variable being passed in itself?

OR, is the use of &x just a place holder for y telling it to use a reference to y (or whatever other variable is passed) as opposed to a copy of y when the function executes?

I see now that this was the source of my initial confusion. I'm just not very certain at all how this works outside of general concept.

Thanks again.

Last edited by sepulture; 11-15-2005 at 04:18 PM.
 
Old 11-15-2005, 04:34 PM   #5
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
a c++ reference is an alias for the variable, what this means is it has some of the function of a pointer(but you cannot move it or make it point to anything else) and it doesn't have the overhead of passing by value. to use a reference you just pass the variable name to a func with accepts a ref. does that help?

Last edited by dmail; 11-15-2005 at 04:50 PM.
 
Old 11-15-2005, 04:53 PM   #6
naf
Member
 
Registered: Oct 2005
Location: Chicago, USA
Distribution: Slackware & Fedora
Posts: 66

Rep: Reputation: 15
Using a pointer to a variable is passing by reference in C. For C++, this feature is retained and is still passing by reference, however, with C++, a the approach for "passing by refernence" is declaring the argument a refernce with the ampersand symbol.

There are more differences here. A reference means that the argument is actually the same object as provided by the caller. A pointer to a variable is actually passing an address by value, however, this allows certain flexability that references prohibit. Primarily, you are allowed to provide constant addresses (useful for hard-coded address) and null pointer can indicate an invalid value with the slight overhead of checking against zero.
Code:
void Write( char *address )
{
    memcpy( address, "Test", 5 );
}

void Write2( double &value )
{
    value = 0.2423;
}

int main()
{
    char buffer[32];
    Write( &buffer );    // Ok.
    Write( 0 );  // <-- Oops!!  Null pointer!
    Write( 0x03432 );   // <-- Oops!!  Unknown address!

    double d;
    Write2( 0 );  // Error, not a reference!
    Write2( &d );  // Error.  Address of double (i.e. double* ) is not a double.
    Write2( d );  // Ok.

    return 0;
}
Both pointers and references avoid copying the referred object. This is usually a good thing, however, that means that the input argument should not be 'trashed' if still needed by the caller.
 
Old 11-15-2005, 04:55 PM   #7
sepulture
LQ Newbie
 
Registered: Nov 2005
Distribution: RH9
Posts: 8

Original Poster
Rep: Reputation: 0
YES!!!

I understand. Thank you so much. You said more in those 2 lines than I was able to get from my 4 books.

To make sure I understand, if a function is written to accept a reference as the arguement:

Code:
int somefunc(&somevar)
{
......
}
then any variable you actually pass into it is passed by reference? So there is no need to actually make a reference to the desired variable for the sake of passing by reference. It is just a way to tell the funtion to accept the variable by reference not value?

Like:

Code:
somefunc(somevar);
coupled with the above code would pass somevar by reference with no need to create a reference to somevar?


This leads me to another question. In the function prototype, you dont need the name of the actual variable to be passed in, correct? If so, what does the prototype need? I am assuming the variable type?

Thank you ever so much.

Last edited by sepulture; 11-15-2005 at 05:08 PM.
 
Old 11-15-2005, 05:00 PM   #8
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
just a little mistake naf
Quote:
Originally posted by naf
Code:
int main()
{
    char buffer[32];
    Write( &buffer );    // <-------------------not ok this is a pointer to a pointer
    Write( buffer );     //OK
    Write( 0 );  // <-- Oops!!  Null pointer!
    Write( 0x03432 );   // <-- Oops!!  Unknown address!

    double d;
    Write2( 0 );  // Error, not a reference!
    Write2( &d );  // Error.  Address of double (i.e. double* ) is not a double.
    Write2( d );  // Ok.

    return 0;
}
 
Old 11-15-2005, 05:03 PM   #9
naf
Member
 
Registered: Oct 2005
Location: Chicago, USA
Distribution: Slackware & Fedora
Posts: 66

Rep: Reputation: 15
Good catch dmail.
 
Old 11-15-2005, 05:06 PM   #10
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
Hey im on fire with my pointer questions today
 
Old 11-15-2005, 05:21 PM   #11
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
Quote:
then any variable you actually pass into it is passed by reference? So there is no need to actually make a reference to the desired variable for the sake of passing by reference. It is just a way to tell the funtion to accept the variable by reference not value?
correct


[quote]
This leads me to another question. In the function prototype, you dont need the name of the actual variable to be passed in, correct?
Quote:
correct
Quote:
If so, what does the prototype need? I am assuming the variable type?
im not quite sure about this one, maybe someone can verify it
for a normal func which takes an int as a paramter and returns nothing the following is suffisant as a prototype
void foo(int);

for a func which takes a ref to an int and returns nothing
Code:
void foo(int&);
damn smilies


edit--
yes the reference prototype is correct, to be honest i dont use references alot in my code i prefer pointers, maybe this is because i learnt c before c++

Last edited by dmail; 11-15-2005 at 05:32 PM.
 
Old 11-15-2005, 07:51 PM   #12
sepulture
LQ Newbie
 
Registered: Nov 2005
Distribution: RH9
Posts: 8

Original Poster
Rep: Reputation: 0
Again, thank you so much. I believe i finally understand.

I am about to rewrite (edit really, no sense in actually rewritting it) my project with this new understanding. I will reply here with my results.
 
Old 11-15-2005, 10:23 PM   #13
sepulture
LQ Newbie
 
Registered: Nov 2005
Distribution: RH9
Posts: 8

Original Poster
Rep: Reputation: 0
Well, I am here to say thank you again. It would seem that I have a somewhat firm grasp on the idea of passing variables to functions by reference now (using references anyway, pointers are another issue but I have used them without too much problem as of yet). The code did exactly what I wanted it to do and aside from a couple of oversights (typo's) compiled without a hitch.

I have also went back and looked at some code examples that previously eluded me and they also make much more sense now. For this I also thank you for the indirect help you gave me.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
"undefined reference" to a template class function btb Programming 3 08-25-2005 05:02 PM
Bash Script Passing variable to Function nutthick Programming 2 02-02-2005 05:15 AM
passing passing variable in Java as reference djgerbavore Programming 3 11-10-2004 02:18 PM
A main can be changed by a function local without passing anything to the function? ananthbv Programming 10 05-04-2004 01:31 PM
a class with a ifstream member Hano Programming 2 04-24-2002 11:01 AM


All times are GMT -5. The time now is 07:37 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration