Clarification on the ampersand...

So I understand the idea of the "&". But I have some applications were I wanted to make sure I understand the effect in specific situations. First, I will give a simple class and then pose the questions...

So say that I have a class called "personClass". Basically this...

1
2
3
4
5
6
7
8
class personClass
{
private:
   int height;
   string name; //include <string>

//functions coming later
}


Question 1: In a function declaration like...
 
personClass& setFirstName(int a, string b);


If I just called it like the following example, because of the ampersand that would modify the class used to call it right?
Example:
1
2
personClass classA;
classA.setFirstName(5,Bob);

So whatever the function did, changes would be on classA?


Question 2: This question is about overloading, say for example, the equals sign. Here's the declaration in the class:

 
const personClass& operator=(const personClass&);

That is an example from my book with no explanation. So why do you need the ampersands in both places and how does the const effect this statement? In my mind I get the ampersand, so then I am modifying the actual class right? But then doesn't the const make it so it does't? The ampersand in both places is confusing me because shouldn't it only be needed the first time and then not be const?



Last edited on
1. Please use code tags.

2. Revise Your Post (Question 3?)

Code Tags in...
1
2
3
4
5
6
7
/*
 * R - the return type
 * f - the function name
 * T - the first parameter's type
 * x - the first parameter's name
 */
R f(T x, ...);

In the example you have above: personClass& setFirstName(int a, string b);. The function personClass::setFirstName takes an int and a string and returns a person& (a person reference.)

Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <string>

using namespace std;


class Person
{
 private:
    int height;
    string name;

 public:
    Person& setHeight(int);
    Person& setName(string);
    int getHeight() const;
    string getName() const;
};

Person& Person::setName(String name) {
    this->name = name;
    return *this;
}

Person& Person::setHeight(int height) {
    this->height = height;
    return *this;
}

string Person::getName() const {
    return this->name;
}

int Person::getHeight() const {
    return this->height;
}

//------------------------------------------------------------------------------
using namespace std;

int main() {
    Person p; //creates a Person using the default constructor
    p.setName("wondernate"); //passes "wondernate" into name, and returns a reference to p
    p.setHeight(2); //passes 2 into height, and returns a reference to p
    cout << p.getName() << ' ' << p.getHeight() << endl;
    return 0;
}
//Here both mutator (set) methods are used in void context, so we don't utilize their return values.
// They could have been written as void methods and the above code would still work.
// However, we could have written the main function as follows instead:
int main() {
    Person p;
    cout << p.setName("wondernate").setHeight(2).getName() << ' ' << p.getHeight << endl;
    return 0;
}
//Now the mutator methods' return values are being utilized;
//although, that is a bit harder to read in my opinion. 

Edit: "accessor" = get, "mutator" = set
Last edited on
Whoa! That second example blew my mind! You rock.


So I am still a bit confused on that second question though? What's the deal with the two const's?
It's returning a const reference. Usually the operator = is overloaded to return a reference so that you can do things like this:
1
2
3
4
5
6
7
8
9
10
Person r;
r.setName("Mathhead200");

Person p, q;
p = q = r; //Here, r is copied to q, and then q is copied to p

//similar to how you can do:
int z = 5;
int x, y;
x = y = z; //x, y, and z all equal 5 

However, it returns a const reference so that you can't do things like this:
1
2
3
Person p, q;
p.setHeight(678);
(q = p).setName("w/e"); //p is copied to q, then setName is invoked on q, but setName is not a const method so ERROR! 

Note: I edited my last post on lines 15, 17, 30, and 34 so that the class accessor methods would be const (can be called by const person objects.)
Last edited on
Topic archived. No new replies allowed.