0

So for my task, I have 3 classes, Student, Date, and Address. Student class has two instances of the Date class and one of the Address class.

My goal is to be able to from the main.cpp create an array of objects from the Student class. I have tried a few different ways but I run into various problems.

edit: This has been marked as a duplicate but all of the other questions I find don't fully/sufficiently answer my question for what I am trying to do here, please link me to a question that does as I cannot find it. I am trying to create an object from class Student that also has objects from classes date and address.

Here is my code now in relevant files.

student.cpp

#include "student.h"


using namespace std;

Student::Student(){
Student::fName = "";
Student::lName = "";
Student::gpa = "";
Student::credits = "";
Student::address;
Student::dBirth;
Student::dGraduation;



}//end Default Constructor

Student::Student(string firstName, string lastName, string s_gpa, string s_credits, Date *s_dBirth, Date *s_dGraduation, Address *s_address){
Student::fName = firstName;
Student::lName = lastName;
Student::gpa = s_gpa;
Student::credits = s_credits;
Student::dBirth = s_dBirth;
Student::dGraduation = s_dGraduation;
Student::address = s_address;


}//end Constructor

student.h

#ifndef STUDENT_H
#define STUDENT_H

#include <string> 
#include <iostream>
#include "date.h"
#include "address.h"

class Student{
private:
    std::string fName;
    std::string lName;
    std::string gpa;
    std::string credits;
    Date *dBirth;
    Date *dGraduation;
    Address *address;

public:
    Student();//Default constructor
    Student(std::string fName, std::string lName, std::string gpa, std::string credits, Date *dBirth, Date *dGraduation, Address *address);//Constructor
    ~Student();//Destructor


};//end Student Class


#endif // STUDENT_H

date.cpp

#include "date.h"

using namespace std;

Date::Date(){
Date::month = 0;
Date::day = 0;
Date::year = 0;
}//End default constructor

Date::Date(int sMonth, int sDay, int sYear){
Date::month = sMonth;
Date::day = sDay;
Date::year = sYear;

}//End constructor

date.h

#ifndef DATE_H
#define DATE_H

#include <string>
#include <iostream>


class Date{
private:
    int month;
    int day;
    int year;
public:
    Date();
    Date(int month, int day, int year);
    std::string getDate();
};//end Date Class

#endif // DATE_H

address.cpp

#include "address.h"

using namespace std;

Address::Address(){
Address::aLine1 = "";
Address::aLine1 = "";
Address::city = "";
Address::state = "";
Address:zip = "";
}//end Default Constructor

Address::Address(string line1, string line2, string sCity, string sState, string sZip){
Address::aLine1 = line1;
Address::aLine2 = line2;
Address::city = sCity;
Address::state = sState;
Address::zip = sZip;

}//End Constructor

address.h

#ifndef ADDRESS_H
#define ADDRESS_H

#include <string>
#include <iostream>


class Address{
private:
    std::string aLine1;
    std::string aLine2;
    std::string city;
    std::string state;
    std::string zip;
public:
    Address();
    Address(std::string aLine1, std::string aLine2, std::string city, std::string state, std::string zip);
    std::string getAddress();
};

#endif // ADDRESS_H

I am fairly new to C++, any and all help is greatly appreciated.

Andy C
  • 21
  • 5
  • At least one cpp file in your project needs to have a `int main()` function or you have to change the linking options to build a library. – user4581301 Jul 31 '15 at 06:28
  • I have a main.cpp file with an int main(), where I include student.h, do I need another int main() on top of that? – Andy C Jul 31 '15 at 06:33
  • Please do not mark this as a duplicate and link me to the @WinMain16 thread, as that is not my main problem or question that I am asking. I will delete that from my question if I must. But I am really trying to get an answer to the question about objects. – Andy C Jul 31 '15 at 06:43
  • Assuming main.cpp includes Student.h, you should be able to `Student WholeBunchaStudents[100];` If you want a variable number, rather than just 100 Students, `Student * WholeBunchaStudents = new Student[numberOfStudents];`and a corresponding `delete[] WholeBunchaStudents;`when you are done, but you have left yourself with no way to assign values to the members of Student. The proper solution is to use `std::vector WholeBunchaStudents`, but this is probably an assignment from a teacher who'd rather you learn how to use C++ wrong. Sigh. – user4581301 Jul 31 '15 at 06:59
  • @πάντα ῥεῖ Andy was asking about passing objects between classes. The compiler error mentioned at the end was not really his question. If the question about class within a class is a duplicate (which it probably is), then the redirect should point there, not to an answer about undefined main(). – riderBill Jul 31 '15 at 08:17
  • @AndyC Since πάντα ῥεῖ marked this as a duplicate, I'll just comment here. It is ok for a class to contain a member field that is itself an object (as opposed to a pointer to an object). In your example above, that would be a better idea, since the information pointed to, e.g. the birth date, can change outside of the object (so you could wind up with student1 having student2's birthday, etc. Also, initialization lists will help you streamline your constructors (google it). – riderBill Jul 31 '15 at 08:22
  • @riderBill Since the error message was edited out, I reopened the question. Though I don't think it's a very good one. – πάντα ῥεῖ Jul 31 '15 at 08:49
  • A side-note - your Student class doesn't offer any access to its internal members once it has been created since all of them are private and the only public methods you have are the constructor and destructor. Also considering the task at hand (Students, dates, addresses etc.) you might want to add setters (not for all member though) in order to be able for example to change the address of a stundent later on – rbaleksandar Jul 31 '15 at 09:48
  • Since we don't have your main() method and cannot see what you have tried so far and what error you get I'll make the assumption that you have difficulties with the pointer-part in your task (Date and Address arguments in your Student constructor), right? – rbaleksandar Jul 31 '15 at 09:51
  • Consider marking the answer as such if you are satisfied so that the issue can be closed or ask for additional information if something is unclear. – rbaleksandar Aug 02 '15 at 18:25
  • The issue was with C::B, not my code and has been resolved – Andy C Aug 02 '15 at 23:31

1 Answers1

0

First of all add your main() so that we can see what goes wrong. Second - I presume you have a problem with the pointer part. See the documentation on the new operator in C++ (also check the delete operator).

Basically you have two easy to use ways of passing object:

  • You can dynamically allocate the object using the new operator and pass the pointer to your Student - this has the disadvantage that you have to manually deallocate the memory for the dynamically allocated object (using delete or delete[] in case of an array)
  • Create objects on the stack - this has the advantage that you need not concern yourself with the memory management.

Example (using new):

Date* d1 = new Date(...);
Date* d2 = new Date(...);
Address* a = new Address(...);
Student* s = new Student(..., d1, d2, a);

...

delete d1;
d1 = NULL;
delete d2;
d2 = NULL;
delete a;
a = NULL;
delete s;
s = NULL;

If you want to do that you can also add the delete-s in the destructor of your Student class:

Student::~Student()
{
  delete dBirth;
  dBirth = NULL;
  delete dGraduation;
  dGraduation = NULL;
  delete address;
  address = NULL;
}

Note that you still have to dispose of Student* s using delete.

Example (using stack):

Date d1(...);
Date d2(...);
Address a(...);
Student s(..., &d1, &d2, &a); // the & operator tells the compiler: pass these objects by reference

You can also make a combination of those two ways I have described above. Also your code is somewhat weird as I have mentioned in the comments:

  1. No need of mentioning the various scopes so many times - once you say

    string Address::getAddress() {
      ...
    }
    

    you don't need to explicitly mention the scope of all members you use in its body unless they have a different namespace

  2. Add access to the members of your classes - you have done this (partially) for your Address and Date classes but right now you have NO WAY of accessing Student's members since they are all private! Add get() and/or set(...) methods whenever you see it adequate.

  3. I see your getAddress() and getDate() are empty. I presume you don't know how to implement those. Here is a possible implementation:

    std::string Address::getAddress()
    {
      return aLine1 + " | " + aLine2 + " | " + ... + zip; # + stands for concatenation
    }
    
    # requires #include<sstream>
    std::string Date::getDate()
    {
      std::stringstream ss;
      ss << year << "/" << month << "/" << day;
    
      return ss.str();
    }
    
  4. Use this instead of adding the class scope in front of the variable (example below is for the constructor of Address class):

    Address(std::string aLine1, ...)
    {
      this->aLine1 = aLine1;
      ...
    }
    

    Or simply call the method's parameter in a different way to avoid name conflicts. The good old-fashioned way is to add "_" in front of the name:

    Address(std::string _aLine1, ...)
    {
      aLine1 = _aLine1;
      ...
    }
    

EDIT:

Here is how your headers and sources should be connected:

  1. student.h - include in student.cpp (because student.cpp implements the content you have described in your student.h) and main.cpp (because you want to declare one or more Student objects and do something with those; since student.h includes address.h and date.h when you include student.h in your main.cpp the code there will "see" what's in those headers too)
  2. address.h - include in address.cpp (because address.cpp implements the content you have described in your address.h), student.h (because you have declared that your Student class has one class member of class Address) and main.cpp (because you want to declare one or more Address objects and pass those to a bunch of Student objects)
  3. date.h - include in date.cpp, student.h (because date.cpp implements the content you have described in your date.h) and main.cpp (because you want to declare one or more Date objects and pass those to a bunch of Student objects)

So basically here's a short list of the includes for each of the files (I'm excluding the and all the rest):

  • student.h : address.h, date.h
  • student.cpp : student.h
  • address.cpp : address.h
  • date.cpp : date.h
  • main.cpp : student.h

EDIT: Additional clarification: date.h and address.h are included in student.h, which accordingly is added to the main.cpp. This creates a chain of headers (address.h and date.h are indirectly included in the main.cpp through the student.h) and that is why I have omitted those in the final list.

rbaleksandar
  • 8,713
  • 7
  • 76
  • 161
  • How should I have my student.h/student.cpp constructors set up? in my main.cpp I don't have anything, just trying simple things like `Date d1(0, 0, 0);` I keep getting undefined references. Specifically in that instance I get undefined reference to Date::Date(int, int, int) – Andy C Jul 31 '15 at 19:00
  • Add the headers of your classes. In my case since I didn't want to bother working with 4 files I decided to put everything in a single CPP file (including the headers). Use #include "student.h" and so on at the top of your main.cpp (where main() is placed and instances of the classes created). – rbaleksandar Jul 31 '15 at 19:15
  • Read http://meta.stackexchange.com/a/5222 especially the part about posting school assignments. But still here is a tip - when you use a class (or anything for that matter) that is declared in a separate header, you have to include the header in order for the compiler to be able to see the reference. You not only need the 3 headers in your main() but the student.h also requires the headers for date and address since you have declared members of the Student class to contain those. See my updated answer. – rbaleksandar Jul 31 '15 at 19:50
  • The undefined reference error is likely because you aren't linking your date.cpp (or date.o) file. Is date.cpp included in the compile statement? Another possibility is a typo, maybe a capitol letter or lack thereof? @rbaleksandar: Your summary of includes looks right, but item 2 above says to include student.h in address.cpp. I don't see any reason for that. A future program might use the Date class but not the Student class. If you agree, maybe you can edit that part out to avoid confusion. – riderBill Aug 01 '15 at 21:48
  • Where is this "include student.h in address.cpp"? If you mean "student.h : address.h, date.h" it says "student.h contains 2 includes: address.h and date.h". If you mean 2) from the list it says "address.h is to be included in address.cpp, student.h and main.cpp". Of course the last one (main.cpp) is not required due to the chaining that occurs through the student.h and that is why in the last list I have omitted it. Can you point exactly where I should look and possibly edit what you have mentioned? (quote the sentence please) I seem to be unable to find it. XD – rbaleksandar Aug 02 '15 at 00:00
  • @rbaleksandar: Sorry, I misread item 2 in your summary. My mistake. – riderBill Aug 03 '15 at 14:51
  • No problem. I still added an EDIT to clarify things a little bit more so thanks for the false positive there. :) – rbaleksandar Aug 03 '15 at 17:38