代码在xcode中运行良好,但在命令行中出错

Code runs fine in xcode, but errors out on the command line

本文关键字:命令行 出错 xcode 运行 代码      更新时间:2023-10-16

我正试图学习如何在c++中使用外部类文件,但遇到了瓶颈。在xcode中一切都运行得很漂亮,但是当我试图在命令行中运行它时,我得到了以下错误:

从g++

:

架构x86_64的未定义符号:"GradeBook::GradeBook(std::basic_string, std::allocator>)",引用自:_main in cc9lo3b .o"GradeBook::getCourseName() const",引用自:_main in cc9lo3b .o没有找到架构x86_64的Ld:符号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 forn" << getCourseName() << "!" << std::endl;
} // end function displayMessage

谢谢你看一看!

你不能只编译一个源文件,你需要编译所有的源文件。最简单的方法是将命令行上的所有源文件传递给g++:

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

如果您只编译main.cpp,您将看到关于未定义符号的错误,这些符号将在GradeBook.cpp中定义,例如GradeBook::GradeBook()构造函数。相反,如果只编译GradeBook.cpp,那么对于main.cpp(即main()函数)中定义的任何符号,您将看到关于未定义符号的错误。

这个命令行每次运行时都会重新编译每个源文件。对于像这样的小项目,这很好,因为您不会注意到编译时间,但是随着项目的增长,您会发现只重新编译已更改的文件或包含已更改的头文件要方便得多。您通常会使用诸如GNU Make之类的依赖项跟踪器。在完成依赖性分析之后,它将一次一个地重新编译源文件,如下所示:

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所提到的,为了使用std::string类,您确实需要在源文件中添加#include <string>。通常,不这样做会导致编译器错误,但您的c++标准库实现恰好从<iostream>内部到#include <string>。您不应该依赖这种行为—如果将代码移植到其他平台,它很可能无法编译,因此最好从一开始就避免这种情况。但是,即使没有这个include编译成功,也不会导致您得到的链接器错误。

你忘了

#include <string>

xcode可以从<iostream>间接包含它,但它不是强制的,所以只是自己包含它,以确保安全。