need help with object oriented program in Visual C++ - c++

guys, I have the following code, but I'm getting error at compiling time... the error is at the end. Thanks
1st Class is "Person"
#ifndef PERSON_H//protecting .h files
#define PERSON_H//protecting .h files
#include <iostream>
#include <string>
using namespace std;
class Person
{
public:
Person();
Person(string first, string last)
{
firstName = first;
lastName = last;
}
virtual void setName(string first, string last)
{
firstName = first;
lastName = last;
}
virtual void setWeightAge(int w, int a)
{
weight = w;
age = a;
}
virtual string getFirstName()
{
return firstName;
}
virtual string getLastName()
{
return lastName;
}
virtual int getWeight()
{
return weight;
}
virtual int getAge()
{
return age;
}
virtual void printPerson()
{
cout << "Name: " << firstName << " " << lastName << endl;
cout << "Age: " << age << endl;
cout << "Weight: " << weight << endl;
}
protected:
string firstName, lastName;
int weight, age;
};
#endif
2nd Class is "Student"
#ifndef STUDENT_H//protecting .h files
#define STUDENT_H//protecting .h files
#include <iostream>
#include <string>
#include "Person.h"
using namespace std;
class Student : public Person
{
public:
Student();
Student(Person s)
{
sStudent = s;
}
virtual void setGPA(double g)
{
gpa = g;
}
virtual void setSchedule(string c, string t, string d)
{
stClass = c;
time = time;
days = d;
}
virtual void setGrade(char g)
{
grade = g;
}
virtual double getGPA()
{
if (grade == 'a') { gpa = 4.0; }
if (grade == 'b') { gpa = 3.0; }
if (grade == 'c') { gpa = 2.0; }
else gpa = 0;
return gpa;
}
virtual char getGrade()
{
return grade;
}
virtual void printSchedule()
{
cout << "Class | Days | Time " << endl;
cout << stClass << " | " << days << " | " << time << endl;
}
protected:
string stClass, time, days;
char grade;
double gpa;
Person sStudent;
};
#endif
and Main()
#include <iostream>
#include "Student.h"
using namespace std;
int main()
{
//creating a person
Person john("John", "Smith");
john.setWeightAge(180, 39);
john.printPerson();
//making john a student
Student johnStdntMath(john);
johnStdntMath.setSchedule("Math", "7:45", "M, W");
johnStdntMath.setGrade('b');
johnStdntMath.printPerson();
johnStdntMath.printSchedule();
system("pause");
return 0;
errors:
1>------ Build started: Project: Person, Configuration: Debug Win32 ------
1> main.cpp
1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall Person::Person(void)" (??0Person##QAE#XZ) referenced in function "public: __thiscall Student::Student(class Person)" (??0Student##QAE#VPerson###Z)
1>c:\users\jorge\documents\visual studio 2010\Projects\Person\Debug\Person.exe : fatal error LNK1120: 1 unresolved externals
}

I suggest you double check your is-A and has-A relationships.
Writing Student : public Person says that a Student is-A Person. But later, you have a member variable sStudent of type Person, which says a Student has-A Person, and I'm guessing is not what you really want.
Check out the answers to this question: Inheritance vs. Aggregation for better explanations.

Listen to your linker, it's just as it says: In constructor Student::Student(Person) you're referring to constructor Person::Person(), but you didn't define Person::Person(), not in a way the linker can see when it does its thing with the Student constructor.
Technically, because you are filling in sStudent in the Student constructor's body the compiler first default-initializes the Person object sStudent, and then assigns to it s, the Person parameter of the constructor. If you'd use the initializer list then the Person member wouldn't be default-initialized and then assigned to but rather copy-constructed right away:
Student(const Person& s) : sStudent(s) { }
But the question remains: Why are you publicly declaring a default constructor in Person and not define it?
Also, you have a leak in Student. The string and Person members of Student won't clean up because when a Student object destructs its destructor won't be called. The Person destructor will be called, but not the Student destructor, and the reason being that the destructor of Person is non-virtual.
One more thing: It's a bad idea in object-oriented design in general and C++ in particular to use inheritance for reuse. The reason is that this very often leads to a violation of the LSP. It can also bear a (not major but nonetheless) performance overhead for introducing a virtual table. But it's the correctness that suffers that matters when you pick inheritance when you should really be using delegation.

You are accessing the no argument constructor for Person when you create the johnStdntMath instance. You need to either
Implement Person::Person() or ...
Change Student::Student(Person s) to Student::Student(Person const& s)
There are some other problems in your code as well. Student is-a Person so there is no need for the Student class to have a Person member variable - it shares the instance variables of its base class by virtue of inheritance. In other words, Student extends Person so your program could be written:
int main() {
Student johnStdntMath;
johnStdntMath.setName("John", "Smith")
johnStdntMath.setWeightAge(180, 39);
johnStdntMath.setSchedule("Math", "7:45", "M, W");
johnStdntMath.setGrade('b');
johnStdntMath.printPerson();
johnStdntMath.printSchedule();
return 0;
}
I would also avoid the using namespace std; statement anywhere and especially in a header file. For example, your Student class contains a member variable named time. This will conflict with the std::time_t std::time(std::time_t*) function defined in <ctime> if that header is included before "student.h".

You haven't implement the default constructor Person(),you can write it like this:
Person():weight(0)
,age(0){};
If you just want to complier it, this is enough;
Here are some tips below:
1.Check your mind, does class Student really need a Person member. If you really need it, Student(Person) may add an explicit symbol:
explicit Student(const Person& s) : sStudent(s) {...};
2.In Person.h
protected:
string firstName, lastName;
int weight, age;
the protected may be private?

Related

ambiguous reference error for member variable 'name'

I have declared a variable name within my people class which is producing an ambiguity error. I tried renaming the name variable, avoided using using namespace std, imported the required libraries, replaced character array with string type but it throws same error all the time. I referred to other posts on Stack Overflow but I could not find the solution.
#include <iostream>
#include <cstdlib>
#include <cstring>
class people{
public:
char name[20];
};
class staff : public people {
public:
int i = 3;
};
class manager : public people {
public:
int j = 8;
};
class lecturer : public manager, public staff {
public:
void set(char* a) {
strcpy(name, a);
}
void get(){
std::cout << "Lecturer name: " << name << std::endl << "Number of managers: " << j << std::endl << "Number of staff: " << i << std::endl;
}
};
int main() {
lecturer ob;
ob.i = 1;
ob.j = 6;
ob.set("aaa bbb");
ob.get();
return 0;
}
and the error message is
main.cpp:24:16: error: reference to ‘name’ is ambiguous
strcpy(name, a);
The compiler doesn't know which member 'name' should use in the strcpy function since lecturer inherits from 2 classes which are manager and staff (both have member 'name'), so to tell the compiler who's name should use, to assign manager's name, you can use:
strcpy(manager::name, a);
and for staff's name:
strcpy(staff::name, a);

Having Problem for Object Initialization by Constructor in C++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I want to create a Student object in C++ and it has the properties of name, major, age and id. The object initialization will be done in the main() part and Student object has the get and set methods for all the constructors. I want to print the student objects in the main() part but I get this error:
in C++98 's1' must be initialized by constructor, not by '{...}'
I am using GNU GCC Complier in Codeblocks. I haven't written specifically any code for compiling or debugging.
I tried to initialize the objects by assigning them to this, making them null, giving them zero and random values but they haven't worked.
Student.h file
#ifndef STUDENT_H
#define STUDENT_H
#include <iostream>
#include <string>
using namespace std;
class Student
{
public:
string name, major;
int age, id;
Student(string name, string major, int age, int id);
string getName();
void setName(string name);
string getMajor();
void setMajor(string major);
int getAge();
void setAge(int age);
int getId();
void setId(int id);
};
ostream & operator << (ostream &out, Student &s);
#endif // STUDENT_H
Student.cpp file
#include "Student.h"
#include <iostream>
using namespace std;
Student::Student(string newName, string newMajor, int newAge, int newId)
{
name = newName;
major = newMajor;
age = newAge;
id = newId;
}
string Student::getName(){
return name;
}
void Student::setName(string newName){
name = newName;
}
string Student::getMajor(){
return major;
}
void Student::setMajor(string newMajor){
major = newMajor;
}
int Student::getAge(){
return age;
}
void Student::setAge(int newAge){
age = newAge;
}
int Student::getId(){
return id;
}
void Student::setId(int newId){
id = newId;
}
ostream & operator << (ostream &out, Student &s)
{
out << "Name: " << s.getName() << " Major: " << s.getMajor() << " Age: " << s.getAge() << " Id:" << s.getId() << endl;
return out;
}
Main.cpp file
#include <iostream>
#include <string>
#include "Student.h"
using namespace std;
int main()
{
Student s1 {"John","MATH",24,123456};
Student s2 {"Steve","ENG",22,654321};
cout << s1 << endl;
cout << s2 << endl;
return 0;
}
I expect to print out the properties of the students as a list but when I run it the program crashes and I get this error:
** in C++98 's1' must be initialized by constructor, not by '{...}' **
I fixed my problem. There were a few problems so here I will explain my solutions in detail.
1-My code is written in C++11 syntax but I was using C++98 syntax so I changed my complier to C++11.
2-My initialization was wrong, I used new variables such as newName, newAge... to change the properties of the Student object.
3-My set methods were wrong so I changed them similar to my initialization.
4-I added an opeator to print out properties more easily.
All the changes are updated for the code in the question

how to fix errors in this program and why i m getting it? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
The errors are:
reference to 'name' is ambiguous
reference to 'age' is ambiguous
request for member 'input1' is ambiguous
no matching function for call to 'ashish3::inputage()'
Here is my code:
#include <iostream>
#include <string>
using namespace std;
class ashish
{
protected:
string name;
public:
void input1(string name1)
{
cin >> name1;
name = name1;
}
int age;
};
class ashish2 : public ashish
{
public:
void inputage(int age1)
{
cin >> age1;
age = age1;
}
void display()
{
cout << name;
}
};
class ashish3 : public ashish, public ashish2
{
public:
void showme()
{
cout << "the name is" << name << endl << "the age is " << age << endl;
}
};
int main()
{
ashish3 rocker;
rocker.input1();
rocker.inputage();
rocker.display();
rocker.showme();
return 0;
}
There are two major problems with your code:
Your inputage method expects an integer, but you call it with no parameters. To fix it, just make age1 a local variable instead of a parameter (there's no reason for it to be a parameter).
Your ashish3 class inherits from both ashish and ashish2. By inheriting from ashish2 it also inherits from ashish one more time, since ashish2 on itself inherits from ashish, resulting in inheriting from ashish twice. Thus, all the members of ashish exist in ashish3 twice, causing the first three ambiguity errors. To get around it, only inherit ashish3 from ashish2 (class ashish3 : public ashish2).
#include <iostream>
#include <string>
using namespace std;
class ashish
{
protected:
string name;
public:
void input1(string name1) {
cin >> name1;
name = name1;
}
int age;
};
class ashish2 :public ashish
{
public:
void inputage(int age1) {
cin >> age1;
age = age1;
}
void display()
{
cout << name;
}
};
class ashish3 : public ashish2
{
public:
void showme()
{
cout << "the name is" << name << endl << "the age is " << age << endl;
}
};
int main()
{
ashish3 rocker;
rocker.input1("xasdas");
rocker.inputage(123);
rocker.display();
rocker.showme();
return 0;
}
You got a few errors, you did not call your functions with parameters. You did not add a <string> header which you should add. And you should not make ashish3 inherit from both of ashish1 and ashish2, because ashish2 inherits all functions and variables as ashish class. C++ is a different language than C please delete the C tag.

Error in constructor - C++

I have just learnt some object oriented programming concepts in Python, but I want to transfer this knowledge to C++, and I have trouble with basic implementation that used to be easy using Python.
#include<iostream>
using namespace std;
class Animal{
char name;
int age;
public:
Animal(char name, int age);
};
Animal::Animal(char name, int age) {
this->name = name;
this->age = age;
}
int main()
{
Animal dog ("Megg", 10);
cout << "Name: " dog.name <<endl;
return 0;
}
When I compile this code, I get a lot of messages, such as:
error: no matching function for call to 'Animal::Animal(const char[5], int)'
note: Animal::Animal(char, int) <near match>
note: candidate expects 1 argument, 2 provided
Thanks!
you don't need to do this->name = name in your constructor definition
"Megg" is a string literal. You can cast "Megg" into const char * but not into a char (this was most likely causing your error).
or better yet. You can use the C++ Standard Library string class std::string
#include <iostream>
#include <string>
class Animal{
std::string name;
int age;
public:
Animal(std::string name, int age);
std::string getName() const;
int getAge() const;
};
Animal::Animal(std::string Name, int Age) {
name = Name;
age = Age;
}
std::string Animal::getName() const {
return name;
}
int Animal::getAge() const {
return age;
}
int main()
{
Animal dog ("Megg", 10);
std::cout << "Name: " << dog.getName() << std::endl; // Error in this line. Missing << between "Name: " and dog.name
return 0;
}
Some additional edits:
You should avoid using using namespace std as it takes everything in the Standard Library (from the files you've included) and puts it in the global namespace. You can instead use the scope resolution operator :: as seen above.
When you start working with multiple libraries you may encounter that both have a class named vector or string, or functions with the same name. The way to avoid this is to specify what namespace you want to use.
or alteratively you can do the following:
using std::cout;
using std::endl;
using std::string;
Additionaly in order for you program to work you need a way to access your object's member variables. You could do this by making the variables public or the better practice is to add accessor functions.

Overriding virtual function not working, header files and c++ files

We have a parent class called Student. We have a child class: StudentCS.
Student.h:
#include <iostream.h>
#include<string.h>
#include<vector.h>
#include "Course.h"
class Course;
class Student {
public:
Student();
Student(int id, std::string dep, std::string image,int elective);
virtual ~Student();
virtual void Study(Course &c) const; // this is the function we have a problem with
void setFailed(bool f);
[...]
};
Student.cpp:
#include "Student.h"
[...]
void Student::Study(Course &c) const {
}
And we have StudentCS.h:
#include "Student.h"
class StudentCS : public Student {
public:
StudentCS();
virtual ~StudentCS();
StudentCS (int id, std::string dep, std::string image,int elective);
void Study(Course &c) const;
void Print();
};
And StudentCS.cpp:
void StudentCS:: Study (Course &c) const{
//25% to not handle the pressure!
int r = rand()% 100 + 1;
cout << r << endl;
if (r<25) {
cout << student_id << " quits course " << c.getName() << endl;
}
}
We create student in the main:
Student *s;
vector <Student> uniStudent;
[...]
if(dep == "CS")
s = new StudentCS(student_id,dep,img,elective_cs);
else
s = new StudentPG(student_id,dep,img,elective_pg);
uniStudent.push_back(*s);
Then we call to study, but we get the parent study, and not the child!
Please help!
The code compiles but when run and called on the uniStudent.Study() it uses the parent and not the child
EDIT: after your edit the problem is clear.
The problem is that you are storing base concrete objects in a STL container. This creates a problem called object slicing.
When you add a student to a vector<Student>, since the allocator of the vector is built on the Student class, every additional information on derived classes is just discarded. Once you insert the elements in the vector they become of base type.
To solve your problem you should use a vector<Student*> and store directly references to students in it. So the allocator is just related to the pointer and doesn't slice your objects.
vector<Student*> uniStudent;
...
uniStudent.push_back(s);
uniStudent[0]->study();
Mind that you may want to use a smart pointer to manage everything in a more robust way.