【问题标题】:Interface+Implementation in C++: code does not executeC++中的接口+实现:代码不执行
【发布时间】:2011-08-26 14:06:46
【问题描述】:

我正在阅读 Deitel 关于 C++:如何编程的书。

在一个特定的部分(第 3.9 节)中,他们解释了接口和实现的概念。他们还提供了巩固这一概念的示例代码。

虽然我或多或少地理解了接口和实现分离背后的基本原理,但我无法执行示例代码。示例代码由 3 个文件组成:

1) GradeBook.h

// GradeBook.h
// GradeBook class definition. This file presents GradeBook's public
// interface without revealing the implementations of GradeBook's member
// functions, which are defined in gradebook.3.12.cpp

#include <string> // class GradeBook uses C++ standard string class
using std::string;

// GradeBook class definition
class GradeBook
{
public:
GradeBook( string ); // constructor that initializes courseName
void setCourseName( string ); // function that sets the course name
string getCourseName(); // function that gets the course name 
void displayMessage(); // function that displays a welcome message
private:
string courseName; // course name for this GradeBook
}; // end class GradeBook

2) 成绩册.3.12.cpp

// Fig 3.12: GradeBook.cpp
// GradeBook member-function definitions. This file contains
// implementations of the member functions prototyped in GradeBook.h

#include <iostream>
using std::cout;
using std::endl;

#include <string>
using std::string;

#include "GradeBook.h"

// constructor initializes courseName with string supplied as argument
GradeBook::GradeBook( string name )
{
  setCourseName( name );  // call set function to initialize courseName
} // end GradeBook constructor

// function to set the course name
void GradeBook::setCourseName( string name )
{
    courseName = name; // store the course name in the object
} // end function setCourseName

// function to get the course name
string GradeBook::getCourseName()
{
return courseName; // return object's courseName
}// end function getCourseName

// display a welcome message to the GradeBook user
void GradeBook::displayMessage()
{
// call getCourseName to get the courseName
cout << "Welcome to the grade book for\n" << getCourseName()
    << "!" << endl;
} // end function displayMessage

3) 成绩册.3.13.cpp

// GradeBook class demonstration after separating its interface from its implementation

#include <iostream>
using std::cout;
using std::endl;

#include "GradeBook.h" // include definition of class GradeBook

// function main begins program execution
int main()
{
// create two GradeBook objects
GradeBook gradeBook1(" CS101 Intro to C++ programming ");
GradeBook gradeBook2("CS102 Data Structures in C++");

// display initial value of courseName for each GradeBook
cout << "gradeBook1 created for course: " << gradeBook1.getCourseName()
    << "\ngradeBook2 created for course: " << gradeBook2.getCourseName()
    << endl;

return 0;
}

要执行和获得类似于 Deitel 书中所示的输出,我必须运行文件号 3。o/p 应该是“CS101 Intro to C++ programming”,然后是“CS101 Intro to C++ programming”。换行符。

但是在运行此文件时,我收到以下错误消息 -

Undefined symbols:
"GradeBook::GradeBook(std::basic_string<char, std::char_traits<char>,std::allocator<char> >)", referenced from:
_main in ccaOv3rj.o
_main in ccaOv3rj.o
"GradeBook::getCourseName()", referenced from:
_main in ccaOv3rj.o
_main in ccaOv3rj.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

请解释发生了什么。我查看了有关接口和实现的其他帖子 - 发布解决方案的 ppl 说必须包含主要功能。但我认为这不是这里的问题。这里还有一些我想不通的事情……可能是因为我不是 CS 专业的。

新人,非常感谢。

【问题讨论】:

  • 您的链接器告诉您它在班级成绩簿中找不到已编译的方法。您使用的是什么开发环境?
  • 巴特沃思先生提供了解决方案。我正在使用 g++-4.0
  • 也许这会在你的书中稍后介绍,但建议在你的标题中放置一个包含保护。在这种情况下,这不是问题,所以不要担心。 (别忘了接受下面的答案。)

标签: c++ interface implementation


【解决方案1】:

猜想,您没有链接到通过编译成绩簿 .cpp 文件生成的 .o 文件。试试:

g++ gradebook.3.13.cpp gradebook.3.12.cpp -o myprog

另外,在文件名中使用小写字母是个好主意,因此您的标题应该是gradebook.h,而不是GradeBook.h,但这不会导致您收到来自链接器的错误。文件名中的这些数字(我认为是练习编号)只能长期混淆——我会为每个练习创建单独的目录。

【讨论】:

  • 不,那没用。输出如下: $ g++ gradebook3.13.cpp -o myprog 未定义符号:“GradeBook::GradeBook(std::basic_string, std::allocator >)”,引用自: cczQVios.o 中的 _main cczQVios.o "GradeBook::getCourseName()" 中的 _main,引用自:cczQVios.o 中的 _main cczQVios.o 中的 _main ld:未找到符号 collect2:ld 返回 1 个退出状态 $ g++ Gradebook3.13.cpp main.cpp -o myprog i686-apple-darwin9-g++-4.2.1: main.cpp: 没有这样的文件或目录
  • 关于文件名中的小写字母:我的建议是让文件名与类名的大小写相匹配。但无论您选择哪种样式,最好保持一致(始终使用全小写,或始终使用匹配大小写)。
  • @Kristopher C++ 区分大小写,许多文件系统不区分。
  • @ Butterworth 先生 - 我使用了您提供的命令行。非常感谢。成功了
  • 在我使用过的每一个不区分大小写的文件系统上,#include "GradeBook.h" 都会找到 gradebook.hGRADEBOOK.H 或任何大写字母的名称,所以我认为这并不重要。 YMMV
【解决方案2】:

看起来你只是在编译gradebook.3.13.cpp,而不包括gradebook.3.12.cpp中的函数。这些错误消息意味着链接器找不到GradeBook 类的函数。

如果您使用的是g++,请参阅 Neil Butterworth 的回答,了解有关如何将这两个文件编译并链接到可执行文件中的详细信息。对于其他环境,请查看文档以确定如何将所有源文件添加到“项目”或“工作区”或环境用于将文件收集在一起的任何内容中。

【讨论】:

  • 如何让gradebook.3.13.cpp找到gradebook.3.12.cpp中的功能?
  • @约翰逊先生 - 非常感谢您的帮助。 Butterworth 先生提供了解决方案。
猜你喜欢
  • 2020-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多