0

C++ で外部クラス ファイルを操作する方法を学ぼうとしていて、壁にぶつかりました。xcode ではすべてがうまく動作しますが、コマンド ラインで実行しようとすると、次のエラーが発生します。

g++ から:

アーキテクチャ x86_64 の未定義シンボル: "GradeBook::GradeBook(std::basic_string, std::allocator >)"、参照元: cc9lOO3b.o の _main "GradeBook::getCourseName() const"、参照元: cc9lOO3b の _main。 o ld: アーキテクチャ x86_64 のシンボルが見つかりません collect2: ld は 1 つの終了ステータスを返しました

クラスのソースコードは次のとおりです。

// GradeBook.h header file


#include <iostream>
#include "GradeBook.h" // include definition of class GradeBook

// constructor initializes couseName with string supplied as argument
GradeBook::GradeBook ( std::string name )
: courseName ( name ) // member initializer to initialize courseName
{
    // empty body
} // end GradeBook constructor

// function that sets the course name
void GradeBook::setCourseName ( std::string name )
{
    courseName = name; // store the course name in the objec
} // end function setCourseName

// function that gets the course name
std::string GradeBook::getCourseName() const
{
    return courseName; // returns the object's courseName
} // end function getCourseName

// function that displays a welcome message to the GradeBook user
void GradeBook::displayMessage() const
{
    // this statement calls getCourseName to get the
    // name of the course this Gradebook represents
    std::cout << "Welcome to the grade book for\n" << getCourseName() << "!" << std::endl;
} // end function displayMessage

ご覧いただきありがとうございます。

4

2 に答える 2

0

1 つのソース ファイルをコンパイルするだけではなく、すべてをコンパイルする必要があります。最も簡単な方法は、コマンド ラインですべてのソース ファイルを に渡すことですg++

g++ main.cpp GradeBook.cpp # Other flags (e.g. "-o OutputFile", "-Wall", etc.)

のみをコンパイルすると、コンストラクターなど、main.cppで定義されるシンボルの未定義シンボルに関するエラーが表示されます。逆に、 のみをコンパイルすると、 で定義されているシンボル、つまり関数の未定義シンボルに関するエラーが表示されます。GradeBook.cppGradeBook::GradeBook()GradeBook.cppmain.cppmain()

このコマンド ラインは、実行するたびにすべてのソース ファイルを再コンパイルします。このような小さなプロジェクトの場合、コンパイル時間に気付かないので問題ありませんが、プロジェクトが大きくなるにつれて、変更されたファイルのみを再コンパイルするか、変更されたヘッダーを含める方がはるかに便利であることがわかります。通常、これには GNU Make などの依存関係トラッカーを使用します。依存関係の分析を行った後、次のようにソース ファイルを 1 つずつ再コンパイルします。

g++ main.cpp -c -o main.o $(CXXFLAGS)  # Compile main.cpp
g++ GradeBook.cpp -c -o GradeBook.o $(CXXFLAGS)  # Compile GradeBook.cpp

g++ main.o GradeBook.o $(LDFLAGS)  # Link two object files into executable

もちろん、これを手動で行うこともできますが、すべてのソース ファイルをg++一度に渡す方がはるかに簡単で、コンパイルとリンクをまとめて行うことができます。

Luchian Grigore が述べたように、クラス#include <string>を使用するには、ソース ファイルで必要があります。std::string通常、そうしないとコンパイラ エラーが発生しますが、C++ 標準ライブラリの実装はたまたま#include <string>from inside <iostream>. この動作に依存するべきではありません。コードを他のプラットフォームに移植すると、コンパイルに失敗する可能性が非常に高いため、最初から回避することをお勧めします。ただし、そのインクルードなしで正常にコンパイルされたとしても、リンカー エラーが発生することはありません。

于 2013-06-10T03:43:05.863 に答える
0

するのを忘れた

#include <string>

xcode から間接的に含めることもできますが<iostream>、義務付けられていないため、安全にプレイするために自分で含めてください。

于 2013-06-10T03:31:05.487 に答える