0

I am reading up Deitel's book on C++: How to program.

In one particular section (section 3.9), they have explained the concept of interface and implementation. They have also provided sample code that cements this concept.

Although I have understood, more or less, the fundamental reasoning behind separation of interface and implementation, I can't get the sample code to execute. The sample code consists of 3 files:

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) gradebook.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) gradebook.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;
}

To execute and obtain output similar to the one shown in the Deitel book, I have to run file number 3. The o/p should be "CS101 Intro to C++ programming" followed by "CS101 Intro to C++ programming" on a newline.

However on running this file I get the following error message -

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

Please explain what's going on. I have looked up other posts regarding interface and implementation - the ppl who posted solutions said the main function must be included. But I don't think that is the issue here. There's something else going on here that I can't figure out ... probably coz m not a CS major.

Newy, thanks a lot.

user755939
  • 63
  • 6
  • your linker is telling you that it cannot find the compiled methods in class Gradebook. what development environment are you using? – ThomasMcLeod May 16 '11 at 16:22
  • Mr Butterworth provided the solution. I'm using g++-4.0 – user755939 May 16 '11 at 16:30
  • Perhaps this is covered later in your book, but it's recommended to put an include guard in your header. This is not a problem in this case, so don't fret. (Don't forget to accept an answer below, too.) – Luc Danton May 16 '11 at 16:37

2 Answers2

2

At a guess, you have not linked in the .o file produced by compiling the gradebook .cpp file. Try:

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

Also,, it is a good idea to use lowercase letters in filenames, so your header should be gradebook.h, rather than GradeBook.h, but this will not cause the error you are getting, which is from the linker. And those numbers in the filename (which I take to be the exercise numbers) can only confuse in the long term - I'd create separate directories for each exercise.

  • Nope that didn't work. Output follows: $ g++ gradebook3.13.cpp -o myprog Undefined symbols: "GradeBook::GradeBook(std::basic_string, std::allocator >)", referenced from: _main in cczQVios.o _main in cczQVios.o "GradeBook::getCourseName()", referenced from: _main in cczQVios.o _main in cczQVios.o ld: symbol(s) not found collect2: ld returned 1 exit status $ g++ gradebook3.13.cpp main.cpp -o myprog i686-apple-darwin9-g++-4.2.1: main.cpp: No such file or directory – user755939 May 16 '11 at 16:24
  • Regarding lowercase letters in filenames: My advice would be to have filenames match the case of the class names. But whatever style you choose, it is best to be consistent (always use all-lowercase, or always use matching case). – Kristopher Johnson May 16 '11 at 16:25
  • @Kristopher C++ is case sensitive, many file systems are not. –  May 16 '11 at 16:26
  • @ Mr Butterworth - I used the command line you supplied. Thanks a lot. It worked – user755939 May 16 '11 at 16:28
  • On every case-insensitive file system I've used, `#include "GradeBook.h"` will find `gradebook.h` or `GRADEBOOK.H` or whatever the smashed-case name is, so I don't think it matters. YMMV – Kristopher Johnson May 16 '11 at 16:30
1

It looks like you are only compiling gradebook.3.13.cpp, without including the functions in gradebook.3.12.cpp. Those error messages mean that the linker cannot find the GradeBook class's functions.

See Neil Butterworth's answer for details on how to compile and link both files into an executable, if you are using g++. For other environments, look at the documentation to determine how to add all the source files into a "project", or "workspace", or whatever the environment uses to collect files together.

Kristopher Johnson
  • 81,409
  • 55
  • 245
  • 302