3

I have a project I'm working on that's actually a school project that I did successfully a long time ago. I haven't done C++ in a while, and I'm having a bit of a problem jumping back into it, especially with pointers. My question is, if I need a get and set function like this

    class Student
    {
    private:
            char firstName[64];
            char lastName[64];
    public:
            void setName(char *fName, char *lName);
            void getName(char *fName, char *lName);
    }


    void Student::setName(char *fName, char *lName);
    {
            firstName = *fName;
            lastName = *lName;
    }

when try to make my getName function, I seem to be very confused as to how I'm supposed to return the names with the function returning void. I know that it doesn't really have to return it, if it sets a value to something that can be returned, but I guess i'm rusty enough with pointers that I can't seem to make this work. I've tried things that I think can't work, such as returning values, but i'm not sure what would go in this get function.

    void Student::getName(char *fName, char *lName);
    {

    }

    int main()
    {
            char myFirstName[64] = "John"
            char myLastName[64] = "Doe"


    //testing to see if it's reading the char arrays correctly.
    cout << "Your Name is:" << myFirstName << " "  << myLastName << endl;


    Student aStudent;
    aStudent.setName(myFirstName, myLastName);

    //This part is where i'm confused.  and i'm sure some above is confusing as well.
    getStudent = aStudent.getName();

    }

I thought maybe I could return the private variable via the constructor, but why would I need a get function then? I'm just redoing this old assignment to get back into c++, I've been doing more network admin stuff, and ignored this for long enough to lose my mind apparently. Thanks in advance, and let me know if you need more information, I tried to be thorough.

trueCamelType
  • 2,198
  • 5
  • 39
  • 76
  • Why wouldn't you just return a `char *`? You have to return the type that `name` actually is. You are using the `get()` method to not let anyone access your private variables directly. – Hunter McMillen Aug 01 '12 at 15:43
  • 1
    Off topic, but if it is c++, why dont you just use strings instead of char[] ? It would make life a little easier... – W. Goeman Aug 01 '12 at 15:44
  • 2
    [You need a book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). Your class is all wrong, unless firstName and lastName are intended to be initials. – Benjamin Lindley Aug 01 '12 at 15:44
  • why did you chose to return void on the get method? also, the goal is not quite clear, in the get method, you are trying to set *fName and *lName to Student.firstName and Student.lastName, respectively? – Austin Aug 01 '12 at 15:45
  • Why are you breaking encapsulation with get/set – Martin York Aug 01 '12 at 15:52
  • 1
    @BenjaminLindley I should have been more clear. The method I described is definitely not the best way for this to be done. This is how the teacher asked for it to be done, and I have no idea why. It's been about six years since I was in the class, so I don't remember why he wanted it done this way, or how I did it before, but I did save all of the assignments. As far as the class being wrong, I just forgot to put the array at the end of the line [64]. All I know is the teacher wanted two private variables, a get and set function, both void, both have same arguments, and both arguments are – trueCamelType Aug 01 '12 at 16:16
  • @Slimmons: If the code you put up there is not the code you intended to put up there, then fix it. There's an option to edit your post, right below the tags. By the way, if you're not in class anymore, why are you sticking to the (bad) requirements? – Benjamin Lindley Aug 01 '12 at 16:19
  • 1
    @BenjaminLindley I'm sticking to the (bad) requirements because my opinion and your opinion of what's bad isn't necessarily the correct opinion. I'm assuming there was a reason he wanted it done this way. Can I do this same assignment an easier way, yes, but the fact that I can't do it this way shows I need to learn something about it. And I will edit the code. Thanks for reminding me about editing. – trueCamelType Aug 01 '12 at 16:36
  • 3
    @Slimmons I'm going to argue that there is *no reason* to learn an inferior, C-style way of handling strings in C++ and that you shouldn't continue this exercise. C-strings are so problematic and C++ fixed nearly all the issues with `std::string`. The most likely reason you were asked to do it this way was a teacher that comes from a strong C background and hasn't moved into the C++ way of doing things. – Mark B Aug 01 '12 at 16:41
  • 3
    There are plenty examples on the internet of how to use pointers and C-style strings. This example is among bad ones. It smells! Forget it! If you want to learn how to use strings in C++, have a look at any of answers below which use `std::string`. – Bojan Komazec Aug 01 '12 at 16:42
  • After the edit, your setName function is still wrong. [Click this sentence to learn C++ properly](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). Then, in a year, this assignment will still be on your hard drive, and you can come back to it, if you want. – Benjamin Lindley Aug 01 '12 at 16:52
  • Because of the comments, and the posted links, I am going to abandon the method he asks for in his assignments, and just do the assignments in the way I think they should be done, and post questions from that in here. Thanks for all the responses, and even though I didn't get exactly the responses I expected, I do think everyone made a good point that there is really no reason for me to continue with his assignments as he asked for them. Thanks again. – trueCamelType Aug 01 '12 at 17:26

5 Answers5

7

I've taken the liberty to convert your C-with-classes code to C++ code:

class Student
{
private:
        std::string firstName;
        std::string  lastName;
public:
        void setName(const std::string& fName, const std::string& lName);
        void getName(std::string& fName, std::string& lName);
}

The getName function takes parameters by reference, so any changes to them will reflect outside the function:

void Student::setName(const std::string& fName, const std::string& lName);
{
        firstName = fName;
        lastName = lName;
}
void Student::getName(std::string& fName, std::string& lName);
{
        fName = firstName ;
        lName = lastName ;
}

int main()
{
    std::string myFirstName = "John"
    std::string myLastName = "Doe"


    //testing to see if it's reading the char arrays correctly.
    cout << "Your Name is:" << myFirstName << " "  << myLastName << endl;


    Student aStudent;
    aStudent.setName(myFirstName, myLastName);

Here, the originally empty returnedFirstName and returnedLastName are modified inside the function:

    //This part is where i'm confused.  and i'm sure some above is confusing as well.
    std::string returnedFirstName;
    std::string returnedLastName;
    aStudent.getName(returnedFirstName,returnedLastName);
}
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • [undeclared variable] = [call to function with void return type]? (last line in main) – Benjamin Lindley Aug 01 '12 at 15:59
  • Here are the requirements listed, and once again, I'm not looking for the best way to do this, I know there are several much much easier ways, but the assignment had this listed as the functions void getName(char *fName, char *lName) void setName(char *fName, char *lName) I Have no idea why he wanted it done this way, but since I was going through the old assignments I figured I'd do it how he wanted. Yes, doing it as a string is a better way, but he liked char arrays for some reason.....old people. – trueCamelType Aug 01 '12 at 16:19
  • @BenjaminLindley yeah don't know how that got in there :) – Luchian Grigore Aug 01 '12 at 17:00
4

I would suggest you to use std::string instead of char arrays.

So, your getName function should look like:

 std::string Student::getName()     {
    return firstName + lastName;
 }

Using pointers and returning void can be done too, but is more difficult. Before calling the getName function, you have to allocate an array to keep the string. you code should look like:

char firstName[100]
char lastName[100];
aStudent.getName(firstName, lastName);

And your getName should look like:

void Student::getName(char *fName, char *lName){
   strcpy(fName, firstName);
   strcpy(lName, lastName); 
}

First option is your way to go.

kist
  • 590
  • 2
  • 8
  • Thanks for addressing the problem in the way I asked. I agree string is better, but thanks for showing how you would do it with the char arrays, and get/set name. I still don't have it working, but I'm going to redo the entire thing, and post the question again with better code, and more of an explanation of problems. Thanks again. – trueCamelType Aug 01 '12 at 16:48
2

You have modeled it with out parameters. So You need to do.

char f[64];
char l[64];
aStudent.getName(f, l);

also I am confused. Is it even working at all ? You are just storing char in your Student object. which is neither a char array, not a char*

In C++ there is a std::string and we often avoid C style strings unless it is explicitly required to work with any other library.

There can be several ways to model your Student class.

class Student{
  private:
     std::string firstName;
     std::string lastName;
  public:
     void setName(const std::string& fName, const std::string& lName);
     std::string getName() const;
     void getName(std::string& fname, std::string& lname) const;
}

std::string Student::getName() const{
    return firstName+" "+lastName;
}
void Student::getName(std::string& fname, std::string& lname) const{
    fname = firstName;
    lname = lastName;
}

If you want both first and last name you can model it after std::pair or with boost::tuple

class Student{
  public:
    typedef std::pair<std::string, std::string> NamePairT
  private:
     NamePairT _namePair;
  public:
     void setName(const NamePairT& namePair);
     NamePairT getName() const;
}


void Student::setName(const NamePairT& namePair) const{
    _namePair = namePair;
}
NamePairT Student::getName() const{
    return _namePair;
}

Student s;
s.setName(std::make_pair("Some", "One"));
Student::NamePairT name = s.getName();
std::cout << s.first << " " << s.second;
Neel Basu
  • 12,638
  • 12
  • 82
  • 146
2

First, the "working" code:

#include <string.h>

class Student
{
private:
        char firstName[64];
        char lastName[64];
public:
        void setName(const char *fName, const char *lName)
        {
            strcpy(firstName, fName);
            strcpy(lastName, lName);
        }

        void getName(char *fName, char *lName) const
        {
            strcpy(fName, firstName);
            strcpy(lName, lastName);
        }
};

Now, why you should use std::string instead:

This code is open to buffer overflows. What if the name doesn't fit in the array allocated? For setName, this can be overcome using strncpy since the size of the available buffer is known. For getName, however, the signature your professor gave you has no information about the size of the destination buffer, so it's totally impossible to protect against writing past the end. std::string, on the other hand, both knows its buffer size and can be reallocated to store as much data as needed, so the buffer overflow can't happen.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
0

your method returns void so getStudent = aStudent.getName(); has no meaning. If you are trying to set *fName and *lName to the values of aStudent, you could do something like this

void Student::getName( char *fName, char *lName ){
  fName = firstName;
  lName = lastName;
  }

and set the values in main something like:

char *fName, *lName;
aStudent( fName, lName);
Austin
  • 1,087
  • 3
  • 14
  • 27