0

現在、ユーザーから継承する抽象 User クラスと Student クラスがあります。main から Student クラスのインスタンスを初期化しようとしています。このエラーが表示されます

アーキテクチャ i386 の未定義シンボル: "Student::Student()"、参照元: ccJo7npg.o の _main "Student::~Student()"、参照元: ccJo7npg.o の _main ld: シンボルが見つかりませんアーキテクチャ i386 collect2: ld が 1 つの終了ステータスを返しました

ユーザー クラス:

#include <iostream>
#import <stdio.h>
#import <string.h>
using namespace std;

class User
    {
public:
    void setName(const string n)
{
    name = n;
}
string getName()
{
    return name;
}
void setUsername(const string u)
{
    username = u;
}
string getUsername()
{
    return username;
}
void setPassword(const string p)
{
    password = p;
}
string getPassword()
{
    return password;
}
void setID(const int ID)
{
    this->ID=ID;
}
int getID()
{
    return ID;
}
void setClassID(const int cid)
{
    classID=cid;
}
int getClassID()
{
    return classID;
}
void logOut()
{
    cout<<"you have logged out"<<endl;
}
void print()
{
    cout<< "Student : "<< ID << name << " "<< username << " " << password << endl;
}
virtual void menu()=0;
protected:
   int classID, ID;
   string name, username, password;
};

学生クラス:

#include <iostream>
#include "User.h"
using namespace std;

class Student: public User
{
public:
Student()
{
    classID=0;
    ID=0;
    username="";
    name="";
    password="";
}
~Student()
{
    cout<<"destructor"<<endl;
}
void studyDeck(const int i)
{

}
void viewScores(const int)
{

}
void viewScores()
{

}
virtual void menu()
{
    cout << "Student menu" << endl;
}
};

Main.cpp:

#include <iostream>
#include "User.h"
#include "Student.h"
using namespace std;

int main()
{
    Student s;
    return 0;
}

「 g++ User.cpp Student.cpp main.cpp 」で g++ でコンパイルしています。

ありがとう!

4

1 に答える 1

3

クラス宣言内で定義されているため、GCC は Student コンストラクターとデストラクターのコードを生成しません。そのため、これらのシンボルが見つからず、リンク エラーが発生します。少なくとも、Student コンストラクターとデストラクターの関数本体をクラス宣言の外に移動し、定義で署名のみ (本体なし) を提供する必要があります。

class Student: public User 
{
Student();
~Student();
...
};

これらの関数本体は、クラス定義の後に Student.cpp で次のように定義します。

Student::Student()
{
    classID=0;
    ID=0;
    username="";
    name="";
    password="";
}

Student::~Student()
{
    cout<<"destructor"<<endl;
}

必須ではありませんが、すべての関数定義をその実装から分離する必要があります。これを行うには、Student.cpp ファイルからクラス定義を省略します。代わりに Student.cpp に Student.h を含めます (Student.h を投稿していなくても、正しいか、プログラムがコンパイルされていないように見えます)。つまり、「Student.h」には「class Student { ... };」が含まれます。関数シグネチャのみで中括弧内に関数本体がない場合、"Student.cpp" には、次のような本体を持つすべての関数定義が含まれます。

void Student::menu()
{
    cout << "Student menu" << endl;
}

これを行う場合、Kevin Grant が説明したように、.h ファイルに #ifndef ガードも必要になります。User.cpp と User.h を同じように扱います。

于 2012-07-15T06:06:26.413 に答える