#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
第二课是“学生”
#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
和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;
错误:
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
}
答案 0 :(得分:3)
我建议你仔细检查你的is-A和has-A关系。
写Student : public Person
说学生是一个人。但是后来,你有一个sStudent
类型的成员变量Person
,它表示学生有一个人,我猜你不是你想要的。
查看此问题的答案:Inheritance vs. Aggregation以获得更好的解释。
答案 1 :(得分:1)
聆听你的链接器,就像它说的那样:在构造函数Student::Student(Person)
中你指的是构造函数Person::Person()
,但你没有定义Person::Person()
,而不是在某种程度上链接器可以看到它何时使用Student
构造函数。
从技术上讲,因为您在sStudent
构造函数体中填充Student
,编译器首先默认初始化Person
对象sStudent
,然后分配< / em>到它s
,构造函数的Person
参数。如果您使用初始化列表,那么Person
成员将不会默认初始化,然后分配给,而是立即复制构建:
Student(const Person& s) : sStudent(s) { }
但问题仍然存在:为什么你公开声明Person
中的默认构造函数而不定义它?
此外,Student
发生泄密。 string
的{{1}}和Person
成员将无法清除,因为当Student
对象析构其析构函数时将不会被调用。将调用Student
析构函数,但不会调用Person
析构函数,原因是Student
的析构函数是非虚拟的。
还有一件事:对于面向对象的设计而言,这是一个坏主意,特别是C ++使用继承来重用。原因是这经常导致违反LSP。它还可以承担引入虚拟表的(不是主要的,但仍然是)性能开销。但是当你真正使用委托时,选择继承时,这是正确的。[/ p>
答案 2 :(得分:1)
在创建Person
实例时,您正在访问johnStdntMath
的无参数构造函数。你需要
Person::Person()
或...... Student::Student(Person s)
更改为Student::Student(Person const& s)
您的代码中还存在其他一些问题。 Student
is-a Person
所以Student
类不需要Person
成员变量 - 它可以凭借其共享基类的实例变量继承。换句话说,Student
扩展Person
,因此可以编写您的程序:
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;
}
我也会在任何地方避免使用using namespace std;
语句,特别是在头文件中。例如,您的Student
类包含名为time
的成员变量。如果在std::time_t std::time(std::time_t*)
之前包含该标头,则会与<ctime>
中定义的"student.h"
功能冲突。
答案 3 :(得分:0)
您尚未实现默认构造函数Person()
,您可以这样写:
Person():weight(0)
,age(0){};
如果你只是想要编译它,这就足够了;
以下是一些提示:
1.检查你的想法,班级Student
确实需要Person
成员。如果您确实需要,Student(Person)
可能会添加explicit
符号:
explicit Student(const Person& s) : sStudent(s) {...};
2.在Person.h
protected:
string firstName, lastName;
int weight, age;
protected
可能是private
?