|
|
|||
![]() |
Department of Engineering |
| University of Cambridge > Engineering Department > computing help > Languages > C++ |
There are many ways to get values in and out of functions, some of which only pertain to member functions. By careful use of const you can make your code safer, ensuring that variables that shouldn't change are protected from accidental modification.
Here's a simple function which given an integer returns 3 times that integer
int triple(int number) {
number=number*3;
return number;
}
int main() {
i=7;
int j = triple(i)
}
i is "passed by value", meaning that number is initially given the value that i has, but after that there's no connection between the variables. At the end i will be 7 and j will be 21.
Sometimes you want to change a variable by passing it to a function. In that situation you need to use "call by reference"
int triple(int& number) { // note the ampersand
number=number*3;
return number;
}
int main() {
i=7;
int j = triple(i)
}
Here number is a sort of alias for main's i. After the call to triple, main's i will be 21, and so will j.
The const keyword can be used in several ways to prevent values being changed. For example, were the previous example's triple changed to the following, the code wouldn't compile, because number can't be changed.
int triple(const int& number) {
number=number*3;
return number;
}
We'll see more uses of const later.
When calling a routine that's inside a class, all of the above options are available, but const can be used in another way. Suppose triple were inside a class called c. Then a triple routine with the following prototype
int c::triple(const int& number) const;
is like the previous example, but the final const keyword means that in addition the function triple can't change the member variables of c. This safety feature is worth using whenever possible. Here's a complete example -
#include <iostream>
using namespace std;
class c
{
public:
int value;
void f(const int& arg) const;
};
// this is a member function of c
void c::f(const int& arg) const {
cout << "arg=" << arg << endl;
// The next 2 lines are commented out - they'd cause compilation errors.
// arg=9;
// value=9;
}
int main()
{
int i;
c test_class;
i=7;
test_class.f(i);
cout << "i=" << i << endl;
}
In C++, references are often used in situations where in the older C language pointers would be used, so if you're already confused by the range of options, it might be best to skip the next section about pointers altogether and go straight onto how to return values.
Pointers are best avoided but you'll need to use them sometimes. Here's the earlier references example rewritten to use pointers
int triple(int* number) {
*number=*number*3;
return *number;
}
int main() {
i=7;
int j = foo(&i)
}
This uses "call by reference" (but not using C++'s reference facility!): changing *number will change the i integer in the calling function.
In C++, references are always const. With pointers there are extra possibilities (and extra chances for confusion) when using const - the position of const is significant
There are many ways that a function f can return an integer value
#include <iostream>
using namespace std;
int* f() {
int j=999;
cout << "j=" << j << endl;
// The following line of code returns a pointer to the integer j.
// Unfortunately j is a local variable whose memory is available
// for recycling once the function's finished. This recycling
// might not happen straight away, but when it does, the 999
// value could be overwritten.
// The line is legal, though some compilers (including the one
// our students use) give a warning.
return &j;
}
int main()
{
int *ip;
ip=f();
cout << "*ip=" << *ip << endl;
}
(not for the faint-hearted!)
const int* c::f(const int * const arg) const;
is a legal declaration. First work out what it means, then write a program which tests to see if your compiler faithfully obeys each of the uses of const.
"C++ Effective Object-Orientated Software Construction", K. Dattatri, Prentice Hall PTR, 2000 has more details.
| | C++ | Languages | computing help | |