Constructor default versus non-default

Simple assignment but my non-default constructor gives me an error that it's looking for 7 variables but finds none. I am doing exactly as the book describes and even my instructor but I'm still getting a compile error.

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
#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Student
{
	public:
	string lastName;		//data member
	string firstName;		//data member
	string middleName;		//data member
	string currentGrade;	//data member
	string Course;			//data member
	int studentNumber;		//data member
	double GPA;				//data member	
	~Student();				//destructor
	
	Student()
	{
		lastName = "Smith";
		firstName = "Sam";
		middleName = "Steve";
		currentGrade = "A-";
		Course = "Chemistry";
		studentNumber = 24680;
		GPA = 2.9;
	}
	
	void Display();
};
	
	
	void Student::Display()
	{
		cout << "This is your students information. "  << endl;
		cout << " Last name is " << lastName << endl;
		cout << " First name is " << firstName << endl;
		cout << " Middle initial is " << middleName << endl;
		cout << " Current grade is " << currentGrade << endl;
		cout << " Current course is " << Course << endl;
		cout << " The student number is " << studentNumber << endl;
		cout << " The students current GPA is " << GPA << endl;
	}
			
int main()
{
	Student student1;
	Student student("Turnham","James","D", "A-","Programming II",12345,3.5);
	
	
	student1.Display();
	student2.Display();
	
	
	
	return 0;
}


I get the error on the line Student student.
Student student("Turnham","James","D", "A-","Programming II",12345,3.5)

You havent made a constructor to take arguments, you only have a default constructor.
I think I got it fixed but i'm getting an error on line 49 where I call student2 and line 53 where I call the display student2.

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
#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Student
{
	public:
	string lastName;		//data member
	string firstName;		//data member
	string middleName;		//data member
	string currentGrade;	//data member
	string Course;			//data member
	int studentNumber;		//data member
	double GPA;				//data member	
	
	Student()
	{
		lastName = "Smith";
		firstName = "Sam";
		middleName = "Steve";
		currentGrade = "A-";
		Course = "Chemistry";
		studentNumber = 24680;
		GPA = 2.9;
	}
	Student set_values(string, string, string, string, string, int, double);
	~Student();				//destructor
	void Display();
};
	
	
	void Student::Display()
	{
		cout << "This is your students information. "  << endl;
		cout << " Last name is " << lastName << endl;
		cout << " First name is " << firstName << endl;
		cout << " Middle initial is " << middleName << endl;
		cout << " Current grade is " << currentGrade << endl;
		cout << " Current course is " << Course << endl;
		cout << " The student number is " << studentNumber << endl;
		cout << " The students current GPA is " << GPA << endl;
	}
			
int main()
{
	Student student1;
	Student student2.set_values ("Turnham","James","D", "A-","Programming II",12345,3.5);
	
	
	student1.Display();
	student2.Display();
	
	
	
	return 0;
}
Just curious, why are you doing this all in one file? It'd be much easier if you broke it up into a main.cpp, student.cpp, and student.h

Also, why are all of the data members like GPA, studentNumber, etc public? It's good practice to keep those private, and perhaps for the private data members use names like m_lastName, m_GPA, etc. Just something different so that way when you set up your constructor you can set it with statements like m_lastName = lastName (lastName being the info read in, being set to the private data member)

that said, I'm confused why you have something names "set_values" rather than an overloaded constructor

It'd be far easier to do something like this:
1
2
3
4
5
6
7
8
9
Student::Student(string lastName, string firstName, string middleName, string currentGrade, string Course, int studentNumber, double GPA){
     m_lastName = lastName;
     m_firstName = firstName;
     m_middleName = middleName;
     m_currentGrade = currentGrade;
     m_Course = Course;
     m_studentNumber = studentNumber;
     m_GPA = GPA;
}


As you seem to be setting up the constructor like a function. Which isn't necessarily wrong, but with bigger codes it will confuse you and anyone looking at it. This approach allows you to simply declare it in main like this:

 
Student student2("Turnham","James","D", "A-","Programming II",12345,3.5);


The .set_values is unnecessary

Essentially you have your default constructor setup, but look

1
2
3
	Student set_values(string, string, string, string, string, int, double);
	~Student();				//destructor
	void Display();


You have no actual constructor for this. Essentially what this line of your code is saying is:
1. Declare a data member of type Student named set_values with (these parameters)
which is not what you want to be doing. To set it up as a constructor, the name "set_values" is not needed at all. It could also be viewed as setting up a function that returns a value of Student, but I don't think that was the intention either.


Hopefully that wasn't too jumbled up and made some sense haha
Last edited on
I did similar to what you are pointing out but get similar results.

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
#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Student
{
	private:
	string lastName;		//data member
	string firstName;		//data member
	string middleName;		//data member
	string currentGrade;	//data member
	string Course;			//data member
	int studentNumber;		//data member
	double GPA;				//data member
	
	string m_lastName;
	string m_firstName;
	string m_middleName;
	string m_currentGrade;
	string m_Course;
	int m_studentNumber;
	double m_GPA;	
	
	public:
	Student()
	{
		lastName = "Smith";
		firstName = "Sam";
		middleName = "Steve";
		currentGrade = "A-";
		Course = "Chemistry";
		studentNumber = 24680;
		GPA = 2.9;
	}
	Student::student(string lastName, string firstName, string middleName, string currentGrade, string Course, int studentNumber, double GPA)
	{
		m_lastName = lastName;
		m_firstName = firstName;
		m_middleName = middleName;
		m_currentGrade = currentGrade;
		m_Course = Course;
		m_studentNumber = studentNumber;
		m_GPA = GPA;
	};
	void Display()
	{
		cout << "This is your students information. "  << endl;
		cout << " Last name is " << lastName << endl;
		cout << " First name is " << firstName << endl;
		cout << " Middle initial is " << middleName << endl;
		cout << " Current grade is " << currentGrade << endl;
		cout << " Current course is " << Course << endl;
		cout << " The student number is " << studentNumber << endl;
		cout << " The students current GPA is " << GPA << endl;
	};
};
int main()
{
	Student student1;
	Student student2("Turnham","James","D", "A-","Programming II",12345,3.5);
	
	student1.Display();
	student2.Display();
	
	
	
	return 0;
}


I've tried like my book has with m_firstName(firstName) still getting an error.

All i'm trying to do is show a default and non-default constructor. When I try to do the student 2 is where I keep getting errors.
Student::student(string lastName, string firstName, string middleName, string currentGrade, string Course, int studentNumber, double GPA)
Since you're declaring/defining in within the class definition, you don't need the Student:: part:
Student(string lastName, string firstName, string middleName, string currentGrade, string Course, int studentNumber, double GPA)

Changing that much will make it compile, but the output will be slightly messed up.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
string lastName;		//data member
string firstName;		//data member
string middleName;		//data member
string currentGrade;	//data member
string Course;			//data member
int studentNumber;		//data member
double GPA;				//data member

string m_lastName;
string m_firstName;
string m_middleName;
string m_currentGrade;
string m_Course;
int m_studentNumber;
double m_GPA;

What's up with the extra set of data members?
In your second (non-default) constructor, you're setting the ones with the m_ prefix, but in Display, you display the other set of variables.

So instead, I would advise getting rid of those extra variables and changing your constructor to this:
1
2
3
4
5
6
7
8
9
10
Student(string lastName, string firstName, string middleName, string currentGrade, string Course, int studentNumber, double GPA)
{
    this->lastName = lastName;
    this->firstName = firstName;
    this->middleName = middleName;
    this->currentGrade = currentGrade;
    this->Course = Course;
    this->studentNumber = studentNumber;
    this->GPA = GPA;
} // No semicolon needed here 

The this-> part is to differentiate between the lastName member variable of Student and the lastName parameter of the function, and so on.
Alternatively, you could rename the parameters for that constructor so that they don't conflict with your member variable names.
Thank you.

That got it working for me. I didn't realize I didn't need the Student::student2 part.

Also getting rid of that extra set of variables cleaned it up considerable.
I quite like the idea (and it does seem to be a bit of a convention) to name member variables with a leading m_, thus avoiding the use of the this pointer. The parameter names are the same without the m_

It is also a good idea to use initialiser lists with constructors, so I would have done this:

1
2
3
4
5
6
7
8
9
10
11
Student(std::string lastName, std::string firstName, std::string middleName, std::string currentGrade, std::string Course, int studentNumber, double GPA) : //initialiser list colon

    m_lastName(lastName), // commas in the initialiser list
    m_firstName(firstName),
    m_middleName(middleName),
    m_currentGrade(currentGrade),
    m_Course(Course),
    m_studentNumber(studentNumber),
    m_GPA(GPA;
{}


A SetValues function does have a use though - for when one needs to change some values after the object has been constructed.

As KvltKitty mentions, private data members is the way to go, as is splitting the code into Student.h, Student.cpp and main.cpp.

Also, it is a good idea to choose a consistent naming scheme for variables & functions & stick to it. I like CamelCase as in CurrentGrade, others like lowercase with underscores - current_grade.

Here is the Google style guide:

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml


Note that each topic can be expanded to give more detail.

When you have compilation errors, please post them then we can explain what they mean.

Hope all goes well. :+D
Topic archived. No new replies allowed.