🔒 Locked
Passing a ref to another function
Advertisement
Original Post
Hi! I´m practising my C++ for a while and I´ve got a very boring question that I hope you can answer. Imagine I´ve got a function that takes a reference to integer "int &" and returns nothing (void). I wanted to pass that number to another function that also takes a reference to integer but my compiler complains arguing that the caller function cannot convert this parameter from int to int&. Any idea? Oluseyi, are you there? =)
Post some code. There''s no reason that you can''t continue to pass the reference. However, if there''s more you''re accidentally not telling us there''s plenty of things that can be wrong
.
[Resist Windows XP''s Invasive Production Activation Technology!]
[Resist Windows XP''s Invasive Production Activation Technology!]
Making on function dependent on another seems as bad programming practice. I think you should code the two functions independently and make the following call:
main
{
int something=11;
//modify something in both f1 and f2
f1(something);
f2(something);
}
void f1(int& x)
{
...//(For an int I consider this bad programming (unless special circumstaces) - use return)
}
void f2(int& y)
{
...
}
However, a rule that I keep is that a function that modify one variable should return the value. If you modify more than one variable use reference calls. Your call would then be:
something=f2(f1(something));
Note however that some args should be sent by reference unless special circumstances.
If you want this to be done in one call make a new function out of it. This is how I would do it to keep the functions as clean as possible. Maybe someone else has another idea.
I hope this was to some help.
main
{
int something=11;
//modify something in both f1 and f2
f1(something);
f2(something);
}
void f1(int& x)
{
...//(For an int I consider this bad programming (unless special circumstaces) - use return)
}
void f2(int& y)
{
...
}
However, a rule that I keep is that a function that modify one variable should return the value. If you modify more than one variable use reference calls. Your call would then be:
something=f2(f1(something));
Note however that some args should be sent by reference unless special circumstances.
If you want this to be done in one call make a new function out of it. This is how I would do it to keep the functions as clean as possible. Maybe someone else has another idea.
I hope this was to some help.
Haha, yes it might be silly to you. As I said, if I need to return messages (plural) I use refs. As for logging and error messages, I have a class that all others have access to.
If something happen that should not happen this will be recorded by calling the Error handler in the class, without returning the value.
Now, no rule is without exception, I usually return success or failure by my functions. As simple as that. If something bad happens, it will be recorded in the Errlog.txt by the error handler. If I need to check the message, each class could save the last error message in a string that I coud access when the class returns a failure. If I have to return a value as weel as the result of the function I could use both of course.
If I am still silly, I´d like to know why
If something happen that should not happen this will be recorded by calling the Error handler in the class, without returning the value.
Now, no rule is without exception, I usually return success or failure by my functions. As simple as that. If something bad happens, it will be recorded in the Errlog.txt by the error handler. If I need to check the message, each class could save the last error message in a string that I coud access when the class returns a failure. If I have to return a value as weel as the result of the function I could use both of course.
If I am still silly, I´d like to know why
Well, I agree with you. As I said under special circumstances. You would almost never pass an object by value! If you do you might get in trouble creating a local copy that will access the same memory as the passed object and as soon as the function is done the destructor of the copied object will be run...
Well, in worst case. You could avoid this easily. But when we speak about passing parameters I do not generally speak about objects because I rarely pass them and I think you should have very good reasons for passing one. Objects should almost never be passed by value, end of story.
Get into the game, I am using the rule for chars, ints, doubles, floats etc.
Well, in worst case. You could avoid this easily. But when we speak about passing parameters I do not generally speak about objects because I rarely pass them and I think you should have very good reasons for passing one. Objects should almost never be passed by value, end of story.
Get into the game, I am using the rule for chars, ints, doubles, floats etc.
quote:
Original post by
thats a silly rule. simply put then you have no way to return special error messages a la dx.
throw std::exception();
You could also create a new exception class to provide such services as logging, translating message codes into a format to be read by the end user of the software, and so on. The main benefit is the translation of this style of coding:
bool complexfunction()
{
if( !simplefunction1() )
return false;
if( !simplefunction2() )
return false;
if( !simplefunction3() )
return false;
return true;
}
...into this...
void complexfunction()
{
simplefunction1();
simplefunction2();
simplefunction3();
}
...and separate the normal code from the error condition code. This also means that the return value is always free for returning the results of the function (if any), rather than trying to package some kind of error code, and it reduces the need to send pointer/reference parameters to return data.
quote:
Original post by Null and Void
Post some code. There's no reason that you can't continue to pass the reference. However, if there's more you're accidentally not telling us there's plenty of things that can be wrong.
[Resist Windows XP's Invasive Production Activation Technology!]
Ok, here´s the code. It´s in Spanish, but Numero stands for number and modificar stands for modify, so it´s easy. I got two errors from MSVC++ 6.
#include
using std::cout;
using std::endl;
void modificar(int №);
void remodificar(int №);
void reremodificar(int №);
int main()
{
int numero = 5;
modificar(numero);
cout << "Numero vale: " << numero << endl;
return 0;
}
void modificar(int №)
{
remodificar(numero<<1);
return;
}
void remodificar(int №)
{
reremodificar(numero<<1);
return;
}
void reremodificar(int №)
{
numero = numero << 1;
return;
}
--------------------Configuration: Pruebas - Win32 Debug--------------------
Compiling...
Pruebas 2.cpp
C:\Archivos de programa\Microsoft Visual Studio\MyProjects\Pruebas\Pruebas 2.cpp(20) : error C2664: 'remodificar' : cannot convert parameter 1 from 'int' to 'int &'
A reference that is not to 'const' cannot be bound to a non-lvalue
C:\Archivos de programa\Microsoft Visual Studio\MyProjects\Pruebas\Pruebas 2.cpp(26) : error C2664: 'reremodificar' : cannot convert parameter 1 from 'int' to 'int &'
A reference that is not to 'const' cannot be bound to a non-lvalue
Error executing cl.exe.
Pruebas.exe - 2 error(s), 0 warning(s)
Any idea? Thanks a lot!!
Edited by - Ignacio Liverotti on December 24, 2001 4:30:25 PM
Ah, the error is obvious now
. You''re passing a value, not a variable as the reference. I''ll modify your code to what I think you wanted.
[Resist Windows XP''s Invasive Production Activation Technology!]
|
[Resist Windows XP''s Invasive Production Activation Technology!]
The only reason references should be used as parameters is when you want to avoid stack usage, which is both show and inefficient. And they should be const references. For parameters that are "okay" to pass on the stack, pass by value. For everything else, use pointers. Here''s why:
Let''s say that we have a function, myfunc. Just looking at a call to it, can you tell whether or not the arguments (x and y) are going to be changed?
int x = 10, y = 2;
int a = myfunc(x, y);
myfunc have been define any number of ways to make the function call look like that:
int myfunc(int x, int y)
int myfunc(int& x, int& y)
int myfunc(int& x, int y)
int myfunc(int x, int& y)
etc.
Some allow the passed argument to be changed, and others not. And you just can''t tell from a call.
Now, if you followed the convention I suggested where you use pointers with any parameter that will be changed, and the rest are passed by value or const references, it becomes obvious, just from a glance:
int x = 10, y = 2;
int a = myfunc(x, &y);
It''s obvious because, in this convention, the only time we''d ever need the address of an object is when we might be interested in changing it. And if we don''t take the object''s address, then we''ll never be changing it, folling the convention.
Certainly, people argue that this is all a matter of opinion (like the int &x versus int& x argument). But even Bjarne himself suggests not to use references very often.
Let''s say that we have a function, myfunc. Just looking at a call to it, can you tell whether or not the arguments (x and y) are going to be changed?
int x = 10, y = 2;
int a = myfunc(x, y);
myfunc have been define any number of ways to make the function call look like that:
int myfunc(int x, int y)
int myfunc(int& x, int& y)
int myfunc(int& x, int y)
int myfunc(int x, int& y)
etc.
Some allow the passed argument to be changed, and others not. And you just can''t tell from a call.
Now, if you followed the convention I suggested where you use pointers with any parameter that will be changed, and the rest are passed by value or const references, it becomes obvious, just from a glance:
int x = 10, y = 2;
int a = myfunc(x, &y);
It''s obvious because, in this convention, the only time we''d ever need the address of an object is when we might be interested in changing it. And if we don''t take the object''s address, then we''ll never be changing it, folling the convention.
Certainly, people argue that this is all a matter of opinion (like the int &x versus int& x argument). But even Bjarne himself suggests not to use references very often.
merlin9x9: excellent point!
Merlin9x9, while I don''t nescessarily disagree with you, an argument for using references (where pointers could be used) is that an invalid value (NULL) can never be passed. In situations where you don''t really want to check for NULL (let''s ignore assert) references are an easy way out
.
[Resist Windows XP''s Invasive Production Activation Technology!]
[Resist Windows XP''s Invasive Production Activation Technology!]
quote:
Original post by Null and Void
Ah, the error is obvious now. You''re passing a value, not a variable as the reference. I''ll modify your code to what I think you wanted.
|
[Resist Windows XP''s Invasive Production Activation Technology!]
I just didn´t know that I was passing a value. Thanks! You helped me a lot!
Null and Void, that''s a very good point. Even worse, testing for NULL is never enough, since it''s fairly easy to coerce anything into a pointer to anything. On Win32, you''re better off using IsBadReadPtr and/or IsBadWritePtr over the full number of bytes as the object you''re expecting—in an assertion, most likely. But that''s cumbersome, and only really practical for non-release builds. I happen to think that readability is far more important than convenience in this case, but, of course, this is just opinion.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement