[英]need help with object oriented program in Visual C++
伙計們,我有以下代碼,但是我在編譯時遇到了錯誤……錯誤在最后。 謝謝,一等班是“人”
#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
}
我建議您仔細檢查您的is-A和has-A關系。
寫作Student : public Person
說學生是一個人。 但是后來,您有了一個Person
類型的成員變量sStudent
,它說一個Student有一個Person,而我猜這不是您真正想要的。
查看以下問題的答案: 繼承與聚合,以獲得更好的解釋。
聽您的鏈接器,就像它說的那樣:在構造函數Student::Student(Person)
您所指的是構造函數Person::Person()
,但您並未以某種方式定義Person::Person()
鏈接器可以看到它何時使用Student
構造函數執行操作。
從技術上講,由於您是在Student
構造函數的主體中填充sStudent
,因此編譯器首先默認初始化Person
對象sStudent
,然后為其分配 s
,即構造函數的Person
參數。 如果您要使用初始化列表,那么Person
成員將不會被默認初始化,然后被分配給它,而是立即進行復制構造:
Student(const Person& s) : sStudent(s) { }
但是問題仍然存在:為什么要在Person
公開聲明默認構造函數而不定義它?
另外,您還有Student
泄漏。 Student
的string
和Person
成員不會清除,因為當Student
對象破壞其析構函數時將不會被調用。 將調用Person
析構函數,但不會調用Student
析構函數,其原因是Person
的析構函數是非虛擬的。
還有一件事:使用繼承進行重用對於一般的面向對象設計(尤其是C ++)來說是一個壞主意。 原因是,這經常導致違反LSP 。 對於引入虛擬表,它也可能承擔(雖然不是主要的,但主要的)性能開銷。 但是,當您應該真正使用委托時選擇繼承時,所遭受的正確性才是最重要的。
創建johnStdntMath
實例時,您正在訪問Person
的no參數構造函數。 你需要
Person::Person()
或... Student::Student(Person s)
更改為Student::Student(Person const& s)
您的代碼中還有其他一些問題。 Student
是 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
的成員變量。 如果<ctime>
定義的std::time_t std::time(std::time_t*)
函數與"student.h"
之前包含該標頭,則這將發生沖突。
您尚未實現默認的構造函數Person()
,可以這樣編寫:
Person():weight(0)
,age(0){};
如果您只是想編譯它,那就足夠了;
以下是一些提示:
1.檢查一下您的想法,上課的Student
真的需要一個Person
成員Person
? 如果您確實需要, Student(Person)
可以添加一個explicit
符號:
explicit Student(const Person& s) : sStudent(s) {...};
2.In Person.h
protected:
string firstName, lastName;
int weight, age;
protected
可能是private
?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.