0

I am attempting to create a Person class that has values: string name, int age, int height, int weight. I am supposed to instantiate a Person object, give it values, and output those values. Also, I am supposed to have a ModifyPerson function that accepts a Person object as argument, and change the name member variable and output it. Any help would be greatly appreciated.

EDIT: Only issue I currently have with code is properly outputting the member values of person1

EDIT2: Fixed! Thank you Zebrafish

    #include <iostream>
    #include <string>
    using namespace std;

    class Person 
    {
        string name;
        int age, height, weight;
    public:
        void set_values(string, int, int, int);
        string ModifyPerson();
        void coutDetails() const;
    }person1;

    void Person::set_values(string a, int b, int c, int d) 
    {
        name = "Rob";
        age = 19;
        height = 71;
        weight = 180;
    }

    string Person::ModifyPerson()
    {
        string name = "Robert";
        return name;
    }

    void Person::coutDetails() const
    {
        cout << "\nName: " << name << "\nAge: " << age << "\nHeight: " <<         
        height << "\nWeight: " << weight;
    }

    std::ostream& operator<<(const std::ostream&, const Person& person1)
    {
        person1.coutDetails();
        return std::cout;
    }

    int main()
    {
        Person person1;
        person1.set_values("Rob", 19, 71, 180);
        cout << person1 << endl;
        cout << person1.ModifyPerson() << endl;
        return 0;
    }
  • Is the implementation of `ModifyPerson` really a member function? Will it really modify the `name` member or just the *local variable* name? And many other problems. Perhaps you should take a few steps back, get [a few good books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282) and start over? – Some programmer dude Mar 19 '18 at 06:45
  • @Someprogrammerdude I think ModifyPerson is supposed to modify the local variable name, so I tried to make changes on the Class and overall code. Still not sure how to assign/output the values for my Person class and also modify name. – Robert Schwartz Mar 19 '18 at 06:56
  • The `operator<<()` should write to AND return the stream passed to it as an argument, not `std::cout`. `ModifyPerson()` modifies a local variable which has the same name as (i.e. shadows) the class member. Beyond that, editing the question each time you get an answer causes previous answers to be meaningless. Voting to close. – Peter Mar 19 '18 at 08:02
  • I'm voting to close this question as off-topic because OP is apparently editing the question each time an answer is received, which makes those answers meaningless for a subsequent reader. – Peter Mar 19 '18 at 08:03
  • @RobertSchwartz I would definitely revert your edits back to your original post. Your code as it shows now is correct, and my answer doesn't make sense in that respect. Either that, or I agree with Peter that the question should be closed as it's not of much use to others. I wouldn't want to revert it myself, whether I actually could or couldn't. – Zebrafish Mar 19 '18 at 08:15
  • @Zebrafish New to site and didn't realize I should keep original post up. I'm not sure how to close it but I'm not going to revert to original code. – Robert Schwartz Mar 19 '18 at 08:31

1 Answers1

1

The reason this line fails:

cout << person1 << endl;

Is told by the error message:

'<<': no operator found which takes a right-hand operand of type 'Person' (or there is no acceptable conversion)

std::cout, which is an std::ostream object doesn't have an operator << taking a Person object, unless you specifically create one.

The second cout line:

cout << person1.ModifyPerson() << endl;

Fails for a different reason. You definitely have the method ModifyPerson() in your class Person, but there's two problems with it:

1) The return types are different

2) You have defined ModifyPerson() as a global function, not a member class method.

So you need to make sure the return types are the same, and when you define the ModifyPerson() method you should place name of the class before hand, like this:

string Person::ModifyPerson(){}

I have a feeling you already knew this because you prefaced the method set_values with Person::

The code should look something like this:

#include <iostream>
#include <string>
using namespace std;

class Person
{
    string name;
    int age, height, weight;

public:
    void set_values(string, int, int, int);
    string ModifyPerson();
}person1;

void Person::set_values(string a, int b, int c, int d)
{
    name = "Rob";
    age = 19;
    height = 71;
    weight = 180;
}

string Person::ModifyPerson()
{
    string name = "Robert";
    return name;
}

int main()
{
    Person person1;
    person1.set_values("Rob", 19, 71, 180);
    //cout << person1 << endl;
    cout << person1.ModifyPerson() << endl;
    return 0;
}

Also if you want to be able to write cout << person1 you will need write a global function that takes an std::ostream as the first argument, like:

std::ostream& operator<<(const std::ostream&, const Person& person)
{
    person.coutDetails();
    return std::cout;
}

The coutDetails() method of the Person can look like this:

void Person::coutDetails() const
{
    cout << "\nName: " << name << "\nAge: " << age << "\nHeight:" <<
        height << "\nWeight: " << weight;
}

Edit: I noticed you changed your ModifyPerson function since I wrote this answer. That part of it only applies to your original post.

Zebrafish
  • 11,682
  • 3
  • 43
  • 119
  • I actually edited my code according to what you wrote, and everything seemed to clear up except for the part on outputting my class' member values. I still am not sure how to create my own function to basically cout << person1. – Robert Schwartz Mar 19 '18 at 07:25
  • @Robert Schwartz See bottom of my answer the function std::ostream& operator<< ??? If you write that as a global function, obviously where it can see the Person class, ie., underneath it. You can do cout << person1 << endl; How you get to access the private variables in that function is up to you. You can either make your Person member variables public, or probably better, make a function that prints out the members. I'll add a quick example. – Zebrafish Mar 19 '18 at 07:28
  • I appreciate the help, when I created the global function for cout<< and also created the coutDetails() it seemed to work, the only issue I have now is in the global function for cout<< , person1.coutDetails(); says "the object has type qualifiers that are not compatible with the member function "Person::coutDetails". – Robert Schwartz Mar 19 '18 at 07:50
  • @Robert Schwartz Because the ostream& operator<< function takes a const Person& as the second argument, when you call person.coutDetails() from it you need to make sure that Person::coutDetails() is const, by putting const after the closing argument brackets, like I'm shown at the bottom. You should make it const both within the class and in the out-of-class definition. I know, C++ is crazy. – Zebrafish Mar 19 '18 at 08:00
  • Adding const in the Class and to the function saved my life, thanks so much for your help! And yes, c++ has been quite a beast and hopefully it will help me learn more comprehensible languages in the future. – Robert Schwartz Mar 19 '18 at 08:03
  • @Robert Schwartz This kind of makes sense, if you pass a const reference to a function you are saying "I'm not changing anything in this person object." So to then call person.coutDetails() if Person::coutDetails() isn't a const function you're kind of breaking that promise, because a non-const function lets you change the members. So it's kind of like the constness spreads, once it comes in as const it flows through as const unless you cast it away or something. – Zebrafish Mar 19 '18 at 08:04