class / creating a temp object and assign it to invoking object *this

from what i am understanding so far it should look like this?

golfers[i] = golfers[i].setgolf()

the setgolf() member function asks 2 questions from the user to input. these are passed to the class's constructor and a temp object of the class is created using the data gathered. this temp object needs to be assigned to the invoking object (*this).

is the code i posted correct for this problem? i am getting confused as to what would constitute as the invoking object in the code. i mean, i know golfers[i].setgolf(), the golfers[i] right before the dot membership operator is the invoking object. so i assume that the temp object created inside the member function gets automatically assigned to the invoking object, and then it is again assigned to that same golfers[i] object before the assignment operator?

or is the invoking object the code that starts before the assignment operator in this case?
Doesn't make any sense.

Why is setgolf() not just a member function that modifies the data in the class?

The you just have

golfers[i].setgolf()

to modify each array member - no constructors, assignment etc.
i know it does not make sense to do it this way but this is the chapter review question so i am trying to follow it instead of writing it differently to make it work. maybe the review question is written wrongly, i am not sure.

golfers is an instantiation of a class, class golf. setgolf() is a member function of the golf class. the user is prompted to enter how many golfers to enter data for. the program them creates an array of golfers.

there needs to be a constructor that intializes instatiations of a golf class. i have this constructor defined already. it is a constructor with default arguments so it also acts as the default constructor if no arguments are passed to it.

the setgolf() member function of this golf class is an interactive one in that it requests the 2 data inputs from the user in order to instatiate a golfer using the provided input instead of using defaults. it uses the constructor to create the temp object.

the chapter review question calls for this setgolf() function to be called as described. but my problem with this is that it is being demanded that setgolf(), after it gathers the required data from the user, create a temporary golfer object with the supplied data from the user and then assign the temporary golfer to the invoking object, which is *this.

the chapter discussed the "this" pointer, which is automatically assigned to the invoking object. so golfers.setgolf() would make the "this" pointer point to golfers.

it also discussed temporary class objects are created when using assignment. for example;

golf golfers1; //use default constructor to instantiate the golfer.

golfer1 = golf(supply your custom arguments) //will create a temporary golf object and copy it's properties directly to the golfer1 object, overwritting it.

i am getting confused because the question is demanding that somehow this gets performed inside the setgolf() member function of the golf class. and the best way i am getting this work is; golfer1 = setgolf() where setgolf would gather data from user input, create the temp object with this data and assign it to the invoking object *this.
My guess is it is something like this

1
2
3
4
5
6
7
8
9
10
11
12
13
golfer& golfer::setgolf(args)
{
  // create temporary golfer object
  golfer temp;
  
  // code to read data from user modifying the temp object - leaving the current object alone

  if(modification successful)
  {
    *this = temp;
  }
  return *this;
}


I think the idea is that if the user aborts or screws up the object is left in its original state (not half modified)

I'm thinking what mik2718 said based on what you have given us. Maybe you can post the problem verbatim without added comments.
hhmm, i have it returning by value, not by reference. my code works, but i think i still fail the review question because i don't ultimately know if the end result is skewed by the return value.

an array of golfers is initialized with the default constructor. array size is user-dependant. the user then has the option of setting the golfers' data manually. when user enters the manual data mechanism he/she has the option of stopping the data entry prematurely by entering a blank line for the golfer's name. the data is not altered for the subsequent golfers if entering a blank line. of course, user can run through the entire array and enter manual data for all golfers.

golfers[1] = golfers[1].setgolf(); //this would be an example of the member method being called.

so this is my point of confusion. i am confused because i do not know if this calling style satisfies the scenario of a temp object bieing copied into the invoking *this object, as the question review states it should.

member function definition below;

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
golf golf::setgolf() //returns by value
{
    char set_name[40];
    int handi; // for the golfer handicap setting
    std::cout << "\ninteractive function called!  manual entry mechanism.\n";
    std::cout << "\nenter a name (empty line to quit)\n";
    std::cout << ": ";
    while (std::cin.get() != '\n') // input stream cleaning loop is needed due to previous input stream activity.
        continue;
    std::cin.get(set_name, 40);
    if (set_name[0] == '\0') // if an empty line entered, setting values for golfers is cancelled by means of not changing it's default data.
    {
        golf temp_golfer; // create default golfer using the default constructor.  all golfers are created with default values when program starts.
        return temp_golfer; // overwrite default golfer with another one, not changing it's value.
    }
    else // else the default golfer will have it's values changed to the user's input.
    {
        std::cout << "\nenter the handicap: ";
        std::cin >> handi;
        while (!std::cin) // if cin fails, will force user to enter correct data type.
        {
            std::cin.clear();
            while (std::cin.get() != '\n') // input stream cleaning loop
                continue;
            std::cout << "\nplease enter a number!\n";
            std::cout << ": ";
            std::cin >> handi;
        }
        golf real_golfer(set_name, handi); // create temporary object and return it by value.
        return real_golfer;
    }
}
Last edited on
Would you mind just posting the question and I will tell you if you have satisfied the answer. I would be shocked if the book has described such a problem of this type, it would be terrible design (not your code, the problem the book is asking based on your #2 post).
Last edited on
ok. it is sort of lengthy and confusing but i'll post it. the question is asking to redo a question from a previous chapter, but this time to use a class instead of a struct. so i have to alter the original review question to fit the new one.

i will post my source code for both questions and if you have the time to grade it, it would be appreciated. i totally understand if this is too much and won't be butt-hurt if i get no responces so no worries.

these are multi-file programs (header, source, main) but i made them into a single file in order to post them in here easier. they should compile and run with no issues. i took the liberty of enhancing the code to include error handling in regards to the cin stream (in case user enters incorrect data type, goes out of bounds, etc) to catch the error and demand user enters correct data, so code is unnecessarily bloated, i guess.


source work from previous chapter review question. the text from the book is commented inside the source code;

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
//excercise 9-1

#include <iostream>
#include <cstring>

const int Len = 40;
struct golf
{
    char fullname[Len];
    int handicap;
};

// non-interactive version:
//  function sets golf structure to provided name, handicap
//  using values passed as arguments to the function
void setgolf(golf & g, const char * name, int hc);

// interactive version:
//  solicits name and handicap from user
//  and sets the member of g to the values entered
//  returns 1 if name is entered, 0 if name is empty string
int setgolf(golf & g);

// function resets handicap to new value
void handicap(golf & g, int hc);

// function displays contents of the golf structure
void showgolf(const golf & g);

// a loop should solicit input from an array of golf structures and terminate when the array is full or the user enters an empty string
// for the golfer's name.  you should only use these prototyped functions to access the golf structures.

int main()
{

    std::cout << "enter up to 5 golfers to initialize: ";
    int num_of_golfers;
    int choice;
    int result = 1;
    int counter = 0;
    const char name[] = "default name!";
    int hc = 2;
    while (!(std::cin >> num_of_golfers))
    {
        std::cin.clear();
        while (std::cin.get() != '\n') // get rid of the garbage.
            continue;
        std::cout << "please enter a number!\n";
    }

    while (num_of_golfers <= 0 || num_of_golfers > 5)
    {
        if (!std::cin)
        {
            std::cin.clear();
            std::cout << "please enter a number!\n";
        }
        else if (num_of_golfers <= 0)
        {
            std::cout << "\nneed to enter one or more golfers.  enter a proper amoung: ";
        }
        else if (num_of_golfers > 5)
        {
            std::cout << "\ncannot have more than five golfers.  enter a proper amount: ";
        }
        while (std::cin.get() != '\n') // get rid of the garbage.
            continue;
        std::cin >> num_of_golfers;
    }

    golf golfers[num_of_golfers];

    for (int i = 0; i < num_of_golfers && result == 1; i++)
    {
        std::cout << "\nmake selection for golfer #" << i + 1 << std::endl;
        std::cout << "1: manual entry, 2: use defaults for golfer: ";
        while (std::cin.get() != '\n') // get rid of the garbage.
            continue;
        std::cin >> choice;
        while (!std::cin) // user entered letter, cin fails.
        {
            std::cout << "please enter a valid number!\n";
            std::cin.clear(); // must clear the instream first.
            std::cout << "make selection for golfer #" << i + 1 << std::endl;
            std::cout << "1: manual entry, 2: use defaults for golfer: ";
            while (std::cin.get() != '\n') // get rid of the garbage.
                continue;
            std::cin >> choice; // try again.
        }
        while (choice < 1 || choice > 2)
        {
            if (!std::cin)
            {
                std::cin.clear();
                std::cout << "please enter a number!\n";
            }
            else if (choice < 1)
            {
                std::cout << "number cannot be lower than 1!  please select a valid choice\n";
            }
            else if (choice > 2)
            {
                std::cout << "number cannot be greater than 2!  please select a valid choice\n";
            }
            while (std::cin.get() != '\n') // get rid of the garbage.
                continue;
            std::cin >> choice;
        }
        if (choice == 1)
        {
            result = setgolf(golfers[i]);
            counter++;
        }
        else
        {
            setgolf(golfers[i], name, hc);
            counter++;
        }
            if (result == 0)
                break;
    }

    for (int i = 0; i < counter; i++)
    {
        showgolf(golfers[i]);
    }
    std::cout << "press r to reset all the golfers to default handicap: ";
    char reset_golfers;
    std::cin >> reset_golfers;
    if (reset_golfers == 'r' || reset_golfers == 'R')
    {
        std::cout << "\ngolfers reset!\n";
        for (int i = 0; i < counter; i++)
            {
                if (strcmp(golfers[i].fullname, name))
                    handicap(golfers[i], 2);
            }
    }

    std::cout << "\n\nprogram exiting!\n";

    return 0;
}

void setgolf(golf & g, const char * name, int hc)
{
    std::cout << "\nnon-interactive version function called!  using defaults!.\n";
    strcpy(g.fullname, name);
    g.handicap = hc;
}

int setgolf(golf & g)
{
    std::cout << "\ninteractive function called!  manual entry mechanism.\n";
    std::cout << "\nenter a name (empty line to quit)\n";
    std::cout << ": ";
    while (std::cin.get() != '\n') // get rid of the garbage.
        continue;
    std::cin.get(g.fullname, 40);
    if (g.fullname[0] == '\0')
        return 0;
    else
    {
        std::cout << "\nenter the handicap: ";
        std::cin >> g.handicap;
        while (!std::cin)
        {
            std::cin.clear();
            while (std::cin.get() != '\n')
                continue;
            std::cout << "\nplease enter a number!\n";
            std::cout << ": ";
            std::cin >> g.handicap;
        }
        return 1;
    }
}

void handicap(golf & g, int hc)
{
    char name3[50] = "defalut name";
    std::cout << "\nreseting handicap of " << g.fullname << " to " << hc << "!\n";
    g.handicap = hc;
}

void showgolf(const golf & g)
{
    std::cout << "\nshowing the contents of golfer " << g.fullname << "\n";
    std::cout << g.handicap << " handicap value." << std::endl;
}


and now for the source code for the chapter review that i am having trouble with;

will be posted below due to thread length limitations;
There isn't really any difference between a class and a struct, except for the default access level.
do programming excercise 1 from chapter 9 but replace the code shown there with an appropriate golf class decleration. replace setgolf(golf &, const char*, int) with a constructor with the appropriate argument for providing initial values. retain the interactive version of setgolf() but implement it by using the constructor. (for example, for the code for setgolf(), obtain the data, pass the data to the constructor to create a temporary object, and assign the temporary object to the invoking object, which is *this)

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
//excercise 10-3

#include <iostream>
#include <cstring>

class golf
{
private:
    static const int Len = 40;
    char fullname[Len];
    int handicap;
public:
    // non-interactive version:
    //  function sets golf structure to provided name, handicap
    //  using values passed as arguments to the function
    golf(const char * name = "!default name!", int hc = 2); //default constructor

    // interactive version:
    //  solicits name and handicap from user
    //  and sets the member of g to the values entered
    //  returns 1 if name is entered, 0 if name is empty string
    golf setgolf();

    // function resets handicap to new value
    void handicap_();

    // function displays contents of the golf structure
    void showgolf();

    int result();
};

int main()
{

    std::cout << "enter up to 5 golfers to initialize: ";
    int num_of_golfers;
    int choice;
    int result = 1;
    int counter = 0;
    while (!(std::cin >> num_of_golfers))
    {
        std::cin.clear();
        while (std::cin.get() != '\n') // get rid of the garbage.
            continue;
        std::cout << "please enter a number!\n";
    }

    while (num_of_golfers <= 0 || num_of_golfers > 5)
    {
        if (!std::cin)
        {
            std::cin.clear();
            std::cout << "please enter a number!\n";
        }
        else if (num_of_golfers <= 0)
        {
            std::cout << "\nneed to enter one or more golfers.  enter a proper amoung: ";
        }
        else if (num_of_golfers > 5)
        {
            std::cout << "\ncannot have more than five golfers.  enter a proper amount: ";
        }
        while (std::cin.get() != '\n') // get rid of the garbage.
            continue;
        std::cin >> num_of_golfers;
    }

    golf golfers[num_of_golfers];

    for (int i = 0; i < num_of_golfers && result == 1; i++)
    {
        std::cout << "\nmake selection for golfer #" << i + 1 << std::endl;
        std::cout << "1: manual entry, 2: use defaults for golfer: ";
        while (std::cin.get() != '\n') // get rid of the garbage.
            continue;
        std::cin >> choice;
        while (!std::cin) // user entered letter, cin fails.
        {
            std::cout << "please enter a valid number!\n";
            std::cin.clear(); // must clear the instream first.
            std::cout << "make selection for golfer #" << i + 1 << std::endl;
            std::cout << "1: manual entry, 2: use defaults for golfer: ";
            while (std::cin.get() != '\n') // get rid of the garbage.
                continue;
            std::cin >> choice; // try again.
        }
        while (choice < 1 || choice > 2)
        {
            if (!std::cin)
            {
                std::cin.clear();
                std::cout << "please enter a number!\n";
            }
            else if (choice < 1)
            {
                std::cout << "number cannot be lower than 1!  please select a valid choice\n";
            }
            else if (choice > 2)
            {
                std::cout << "number cannot be greater than 2!  please select a valid choice\n";
            }
            while (std::cin.get() != '\n') // get rid of the garbage.
                continue;
            std::cin >> choice;
        }
        if (choice == 1)
        {
            golfers[i] = golfers[i].setgolf();
            result = golfers[i].result();
            if (result == 1)
                counter++;
        }
        else
        {
            counter++;
        }
            if (result == 0)
                break;
    }

    for (int i = 0; i < counter; i++)
    {
        golfers[i].showgolf();
    }

    std::cout << "press r to reset all the golfers to default handicap: ";
    char reset_golfers;
    std::cin >> reset_golfers;
    if (reset_golfers == 'r' || reset_golfers == 'R')
    {
        std::cout << "\ngolfers reset!\n";
        for (int i = 0; i < counter; i++)
            {
                golfers[i].handicap_();
            }
    }
    std::cout << "\n\nprogram exiting!\n";

    return 0;
}

golf::golf(const char * name, int hc)
{
    std::cout << "\nnon-interactive version function called!  using default constructor!.\n";
    strcpy(fullname, name);
    handicap = hc;
}

golf golf::setgolf()
{
    char set_name[40];
    int handi; // for the golfer handicap setting
    std::cout << "\ninteractive function called!  manual entry mechanism.\n";
    std::cout << "\nenter a name (empty line to quit)\n";
    std::cout << ": ";
    while (std::cin.get() != '\n') // input stream cleaning loop
        continue;
    std::cin.get(set_name, 40);
    if (set_name[0] == '\0') // if an empty line entered, setting values for golfers is cancelled by means of not changing it's default data.
    {
        golf temp_golfer; // create default golfer using the default constructor.  all golfers are created with default values when program starts.
        return temp_golfer; // overwrite default golfer with another one, not changing it's value.
    }
    else // else the default golfer will have it's values changed to the user's input.
    {
        std::cout << "\nenter the handicap: ";
        std::cin >> handi;
        while (!std::cin) // if cin fails, will force user to enter correct data type.
        {
            std::cin.clear();
            while (std::cin.get() != '\n') // input stream cleaning loop
                continue;
            std::cout << "\nplease enter a number!\n";
            std::cout << ": ";
            std::cin >> handi;
        }
        golf real_golfer(set_name, handi); // create temporary object and return it by value.
        return real_golfer;
    }
}

void golf::handicap_()
{
    if (fullname[0] != '!')
    {
        std::cout << "\nreseting handicap of " << fullname << " to " << 2 << "!\n";
        handicap = 2;
    }
}

void golf::showgolf()
{
    std::cout << "\nshowing the contents of golfer " << fullname << "\n";
    std::cout << handicap << " handicap value." << std::endl;
}

int golf::result()
{
    if (fullname[0] == '!')
        return 0;
    else
        return 1;
}
retain the interactive version of setgolf() but implement it by using the constructor. (for example, for the code for setgolf(), obtain the data, pass the data to the constructor to create a temporary object, and assign the temporary object to the invoking object, which is *this)


Ok so what this is saying looks different then how you have it implemented. The signature for the interactive setGolf is..

int setgolf(golf & g);

Change it to this:
int setgolf();

Inside your function you will do what you have done but you don't return a golf object or a reference to a golf object, you still return 1 or 0 based on if they enter a name or not. The difference here is this...

Inside setGolf()
1
2
3
4
5
6
7
//Get input...
//Create temp object from input
golf golfer(name,handicap); //This uses the constructor as it states to do.
//Now instead of returning the object you assign it to 'this'
*this = golfer;  //You haven't allocated memory so a shallow assignment works
//...
return name_enterd;


Then in main you just call...
 
golfers[i].setGolf(); //This will now assign the temporary to *this 
Last edited on
thanks for your help. the darn return type of the function should not have been altered, goofy me... i think i instinctively altered it when i started writing the program and never thought about going back to having it return an int again. i will make the minor changes and see how it works out.
it definately works out well :)

not only that, but i can snip the int golf::result() function because i can now use result = golfers[i].setgofl() and it will pass the temp object to golfers[i] and also return the 0 or 1 that is required for the complementary feature during manual input of the golf array.
Topic archived. No new replies allowed.