C++ Interface Compiling - c++

EDIT:
I figured out the solution. I was not adding -combine to my compile instructions and that was generating the errors.
I'm in the process of working through the Deitel and Deitel book C++ How to Program and have hit a problem with building and compiling a C++ interface using g++. The problem is, I've declared the class in the .h file and defined the implementation in the .cpp file but I can't figure out how to get it to compile and work when I try to compile the test file I wrote. The g++ error I'm receiving is:
Undefined symbols:
"GradeBook::GradeBook(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)", referenced from:
_main in ccohy7fS.o
_main in ccohy7fS.o
"GradeBook::getCourseName()", referenced from:
_main in ccohy7fS.o
_main in ccohy7fS.o
ld: symbol(s) not found
collect2: ld returned 1 exit status<
If someone could point me in the right direction I'd be appreciative.
My header file:
//Gradebook 6 Header
//Purpose is to be the class declaration for the class Gradebook 6
//Declare public, privates, and function names.
#include //the standard c++ string class library
using std::string;
//define the class gradebook
class GradeBook
{
public: //all the public functions in the class
GradeBook(string ); //constructor expects string input
void setCourseName (string ); //method sets course name--needs string input
string getCourseName(); //function returns a string value
void displayMessage(); //to console
private: //all private members of the class
string courseName;
}; //ends the class declaration
My .cpp file is:
//Gradebook 6
// The actual implementation of the class delcaration in gradebook6.h
#include
using std::cout;
using std::endl;
#include "gradebook6.h" //include the class definition
//define the class gradebook
GradeBook::GradeBook(string name) //constructor expects string input
{
setCourseName(name); //call the set method and pass the input from the constructor.
}
void GradeBook::setCourseName (string name) //method sets course name--needs string input
{
courseName = name; //sets the private variable courseName to the value passed by name
}
string GradeBook::getCourseName() //function returns a string value
{
return courseName;
}
void GradeBook::displayMessage() //function does not return anything but displays //message to console
{
cout //message here, the pre tag isn't letting it display
} //end function displayMessage
Finally, the test file I wrote to implement the interface and test it.
// Gradebook6 Test
// Program's purpose is to test our GradeBook5 header file and file seperated classes
#include
using std::cout;
using std::endl;
#include "gradebook6.h" //including our gradebook header from the local file.
//being program
int main()
{
//create two gradebook objects
GradeBook myGradeBook1 ("CSC 101 Intro to C++ Programming"); //create a default object using the default constructor
GradeBook myGradeBook2 ("CSC 102 Data Structures in C++");
//display intitial course name
cout //another output message here that the code tag does not like
return 0;
}

Looks like you just need to link in the GradeBook.cpp object file to your final executable. Care to post your makefile or the way you are building it?

What you are seeing are linker errors (the indication is in the "ld returned" bit: ld is the linker). You need to either give all the .cpp files to g++, so it will compile and link them, or use the latter's -c switch to make a .o from the .cpp and then use THAT .o on a further g++ command to build (link) the executables.

Related

a typo on page 252 of the book " a complete guide to c++"?

I'm reading the book "a complete guide to c++". I think there is a typo there on page 252. So I have three files as the following.
In file account.h,
// account.h
// Defining the class Account. class definition (methods prototypes) is usually put in the header file
// ---------------------------------------------------
#ifndef _ACCOUNT_ // if _ACCOUNT_ is not defined
#define _ACCOUNT_
#include <iostream>
#include <string>
using namespace std;
class Account
{
private:
string name;
unsigned long nr;
double balance;
public: //Public interface:
bool init( const string&, unsigned long, double);
void display();
};
#endif
// _ACCOUNT_
In file account.cpp,
// account.cpp
// Defines methods init() and display().
// ---------------------------------------------------
#include "account.h" // Class definition
#include <iostream>
#include <iomanip>
using namespace std;
// The method init() copies the given arguments
// into the private members of the class.
bool Account::init(const string& i_name,
unsigned long i_nr,
double i_balance)
{
if( i_name.size() < 1)
return false; // check data format to make sure it is valid
name = i_name;
nr = i_nr;
balance = i_balance;
return true;
}
// the method display() outputs private data.
void Account::display()
{
cout << fixed << setprecision(2)
<< "--------------------------------------\n"
<< "Account holder:" << name << '\n'
<< "Account number:" << nr << '\n'
<< "Account balance:" << balance << '\n'
<< "--------------------------------------\n"
<< endl;
}
And finally, in file account_t.cpp
// account_t.cpp
// Uses objects of class Account.
// ---------------------------------------------------
#include "account.h" // header file which contains class definition; (prototype for member functions)
int main()
{
Account current1, current2; // create two instances with name current1, current2
current1.init("Cheers, Mary", 1234567, -1200.99);
// have to call the init function to initialize a Account object; init function is public; members properties are private;
// that's why can not do current1.name = "nana" outside of the class definition
current1.display();
// current1.balance += 100; // Error: private member
current2 = current1;
current2.display();
current2.init("Jones, Tom", 3512347, 199.40);
current2.display();
Account& mtr = current1; // create a reference, which points to object current1
mtr.display();
return 0;
}
I do not think it's correct; because obviously there is no way to get access the init member methods and the display member methods, right? I hope this is not a naive question.
EDIT: I tried to run the main function in file account_t.cpp, and got the following output.
~$ g++ account_t.cpp
/tmp/ccSWLo5v.o: In function `main':
account_t.cpp:(.text+0x8c): undefined reference to `Account::init(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long, double)'
account_t.cpp:(.text+0xb6): undefined reference to `Account::display()'
account_t.cpp:(.text+0xd5): undefined reference to `Account::display()'
account_t.cpp:(.text+0x132): undefined reference to `Account::init(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long, double)'
account_t.cpp:(.text+0x15c): undefined reference to `Account::display()'
account_t.cpp:(.text+0x176): undefined reference to `Account::display()'
collect2: error: ld returned 1 exit status
Any more comments are greatly appreciated.
There is no issue with what you are asking about. init and display are declared public in the definition of class Account and the file with the class definition is #includeed properly in the .cpp using these methods.
In order to use a function only its declaration is needed (which is in the class definition in the header which is included). The definition/implementation in the .cpp file is not needed to use the function.
Each .cpp is compiled individually (called a translation unit) and afterwards each use of a function (for which only the declaration might have been available) is linked to the correct definitions from the other translation units if necessary via the function's scope, name and signature. This is called the linking process.
An introductory book to C++ should explain how compilation and linking process work.
For g++, there is an easy way to compile all .cpp files individually as translation units and then directly link them together:
g++ account_t.cpp account.cpp
You always need to add all .cpp to the compiler invocation like that. (There are alternative ways, but this is the easiest one.)
However, as mentioned in the comments there are other issues with this program:
_ACCOUNT_ is a reserved identifier that one may not #define in a program. All identifiers starting with an underscore followed by a capital letter are reserved. Using them causes undefined behavior.
using namespace std; is bad, at the very least when used in a header file, see Why is "using namespace std;" considered bad practice?.
Classes have constructors. One should not write init methods in most cases. The constructor is responsible for constructing and initializing class instances. But no constructor is used in the code.
Money should never be stored in double, because arithmetic with double is imprecise. You should store the value in an integer type in dimensions of the smallest relevant unit of money (e.g. cents).
#include <iostream> is not needed in the header file. One should avoid adding #includes that are not needed.
init returns a boolean indicating successful initialization. But main never checks that value. If a function can fail with an error value, then you must check that error value returned by the function to make sure that continuing the rest of the program is safe.
Some of these points may be excusable as simplification for a beginner program, depending on how far the book got at this point (though 200+ pages should already cover a lot), but others aren't.
Example of constructor use doing the same thing:
class Account
{
private:
string name;
unsigned long nr;
double balance;
public: //Public interface:
Account(const string&, unsigned long, double);
void display();
};
Account::Account(const string& i_name,
unsigned long i_nr,
double i_balance)
: name(i_name), nr(i_nr), balance(i_balance)
{
}
int main()
{
Account current1("Cheers, Mary", 1234567, -1200.99);
// Create Account instance and initialize private members; constructor is public; members properties are private;
// that's why can not do current1.name = "nana" outside of the class definition
current1.display();
// current1.balance += 100; // Error: private member
Account current2 = current1; // Create second Account instance and copy private members from first one
current2.display();
current2 = Account("Jones, Tom", 3512347, 199.40); // Replace instance with a copy of a new one
current2.display();
Account& mtr = current1; // create a reference, which points to object current1
mtr.display();
return 0;
}
The i_name.size() < 1 check (which is weirdly written, why not i_name.size() == 0?) would be realized by throwing an exception from the constructor:
Account::Account(const string& i_name,
unsigned long i_nr,
double i_balance)
: name(i_name), nr(i_nr), balance(i_balance)
{
if(i_name.size() == 0) {
throw invalid_argument("Account does not accept empty names!");
}
}
This requires #include<stdexcept> and is a more advanced topic.

C++ can't define virtual function OUTSIDE classes and header file

As function name had been already declared in header file: function.h and header file were preloaded in OJ, I need to define myAdd in main.cpp, aka OUTSIDE classes. However, most tutorial I can find online about virtual function just define what the function should do INSIDE the class.This is header file:
#ifndef _FUNCTION_H_
#define _FUNCTION_H_
class abstractAdd
{
public:
abstractAdd(){};
~abstractAdd(){};
virtual int myAdd(int a, int b) = 0;
};
class Implement : public abstractAdd
{
private:
public:
Implement();
~Implement();
int myAdd(int a,int b);
};
;
#endif
I have tried this in main.cpp
//include every libraries needed
#include "function.h"
int Implement::myAdd(int a,int b)
{
int c=a+b;
return c;
}
int main(){
abstractAdd& ra = *new Implement();
string input;
while(getline(std::cin, input)){
istringstream testcase(input);
int a,b;
testcase >> a;
testcase >> b;
cout << ra.myAdd(a,b) << endl;
}
return 0;
}
But compiler said:
Undefined symbols for architecture x86_64:
"Implement::Implement()", referenced from:
_main in cc3KANpW.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
How can I implement the function OUTSIDE classes and header files?
new Implement() will create an object. That entails calling the constructor. You declared a constructor Implement();, but didn't define it anywhere.
So the linker is complaining because it can't find the constructor definition.
If you simply wish to use the default constructor as a compiler would define it, you can declare it as follows:
Implement() = default;
It will be defaulted, and defined inline.
Same goes for Implement's destructor as well.
As an aside, while your program is small and probably hosted, it still contains a leak. You allocate with new but don't delete the created object. In real production code, that will be unacceptable. You can simplify your code and rid you self of this concern by using a smart pointer:
std::unique_ptr<abstractAdd> ra = std::make_unique<Implement>();
Now that the object is disposed of correctly when the time comes, you should also make the destructor of abstractAdd virtual as well. Because now you are destroying an object polymorphically.

Why does the C++ Compiler not find the function definitions? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I wrote some code trying to understand the relationship between compiling and linking - and also to see where and if function declarations have to be repeated in source files.
The two files I wrote are:
Person.cpp:
#include <string>
class Person {
public:
Person(std::string name) {
(*this).name = name;
};
std::string getName() {
return name;
};
std::string name;
};
and the file
PersonMain.cpp:
#include <iostream>
class Person {
public:
Person(std::string);
std::string getName();
std::string name;
};
int main(){
Person* charlie = new Person("Charlie");
std::cout << "Hi, my name is " << charlie->getName();
}
I repeat the Class Person and Class Person function declarations (not the definitions) in the PersonMain.cpp.
I now compile and link the two files using the gcc C++ Compiler:
g++ *.cpp -o runthis.exe
I then get the following error message:
PersonMain.cpp:(.text+0xfe): undefined reference to
Person::Person(std::basic_string<char,
std::char_traits<char>,std::allocator<char> >)'
PersonMain.cpp:(.text+0x13c): undefined reference to
Person::getName()' collect2.exe: error: ld returned 1 exit status
It seems the Person Class methods are not found when linking. Why is that? How can I heal this?
ADDENDUM:
I repeated the declaration of Person in PersonMain.cpp explicitly, and didn't but the redeclaration into a header file as would be done normally. So I've done the preprocessor step here already. This faq suggests that:
[The Preprocessor] works on one C++ source file at a time by replacing
include directives with the content of the respective files (which is usually just declarations)[...]
and later on:
[The Linker] links all the object files by replacing the references to
undefined symbols with the correct addresses. Each of these symbols
can be defined in other object files or in libraries.
I add this remark becaue #engf-010 said that a Compilation Unit that has code that isn't actually used in that compilation unit is not compiled, even if it is needed in other compilation units. enf-010 suggests that I put the definition and declaration into the header file, but the faq article says that only the declarations should go there, the definitions can be elsewhere.
Usually one splits declarations and definitions into .h and .cpp files respectively.
Your code would look something like this:
person.h - declarations:
#include <string>
class Person {
public:
Person(std::string n);
std::string getName() const;
std::string name;
};
person.cpp - implementation:
#include <string>
#include "person.h"
Person::Person(const char* n) : name(n) { }
std::string Person::getName () const { return name; }
and personmain.cpp - where you use your class Person:
#include <iostream>
#include "person.h"
int main()
{
Person* charlie = new Person("Charlie");
std::cout << "Hi, my name is " << charlie->getName ();
}
Like #engf mentioned, essentially, what you got in your code is double definition of Person and no implementation. You can't easily define Person in main file and implement Person::Person() somewhere else (and you should not), in another translation unit (i.e., in person.cpp), without letting the compiler know what you implement. You can't forward-declare Person and use it in personmain.cpp like this:
class Person;
...
Person* charlie = new Person("whatever");
because compiler should know complete type to emit code constructing the Person-object. You can't have two definitions of Person. You can't implement members of Person without definitions, accessible to all users of your code. So, what you left with is the scheme like this above.
To elaborate a bit more on compilation and linking, very roughly, when compiler sees a reference to symbol not defined locally in the same translation unit, it puts appropriate record into object file. When this object file is passed to the linker (possibly, along with a bunch of other object files and libraries), linker should resolve such records to symbols (functions, variables etc.) found somewhere in input object files or libraries. If it succeeds in that, it combines all the referenced code into single image. In your case the linker failed to resolve referenced symbol Person::Person for constructor. Probably this is not bad Q&A to start.
what you've got is a definition in one source file and a declaration in the other source file.
When the source file containing the definition is compiled ,the compiler comes to the conclusion that there isn't any 'real' code to generate ,because you didn't use the class.
So you end up with an empty object file.
You can define a class in a source file but if you don't use that class in that file it is tossed away as not being used.
If you use that class in other source files (through it's declaration) the compiler generates code for member accesses ,but those are not found during linking.

Xcode linker command failed issue

Ld /Users/noahheath/Library/Developer/Xcode/DerivedData/NBAPlayer- aeoygjukxhrzaxddvctkqcefsiql/Build/Products/Debug/NBAPlayer normal x86_64
cd /Users/noahheath/Documents/NBAPlayer
export MACOSX_DEPLOYMENT_TARGET=10.9
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -L/Users/noahheath/Library/Developer/Xcode/DerivedData/NBAPlayer-aeoygjukxhrzaxddvctkqcefsiql/Build/Products/Debug -F/Users/noahheath/Library/Developer/Xcode/DerivedData/NBAPlayer-aeoygjukxhrzaxddvctkqcefsiql/Build/Products/Debug -filelist /Users/noahheath/Library/Developer/Xcode/DerivedData/NBAPlayer-aeoygjukxhrzaxddvctkqcefsiql/Build/Intermediates/NBAPlayer.build/Debug/NBAPlayer.build/Objects-normal/x86_64/NBAPlayer.LinkFileList -mmacosx-version-min=10.9 -stdlib=libc++ -Xlinker -dependency_info -Xlinker /Users/noahheath/Library/Developer/Xcode/DerivedData/NBAPlayer-aeoygjukxhrzaxddvctkqcefsiql/Build/Intermediates/NBAPlayer.build/Debug/NBAPlayer.build/Objects-normal/x86_64/NBAPlayer_dependency_info.dat -o /Users/noahheath/Library/Developer/Xcode/DerivedData/NBAPlayer-aeoygjukxhrzaxddvctkqcefsiql/Build/Products/Debug/NBAPlayer
duplicate symbol __ZN9NFLplayerC1Ev in:
/Users/noahheath/Library/Developer/Xcode/DerivedData/NBAPlayer-aeoygjukxhrzaxddvctkqcefsiql/Build/Intermediates/NBAPlayer.build/Debug/NBAPlayer.build/Objects-normal/x86_64/UnsortedStruct.o
/Users/noahheath/Library/Developer/Xcode/DerivedData/NBAPlayer-aeoygjukxhrzaxddvctkqcefsiql/Build/Intermediates/NBAPlayer.build/Debug/NBAPlayer.build/Objects-normal/x86_64/main.o
duplicate symbol __ZN9NFLplayerC2Ev in:
/Users/noahheath/Library/Developer/Xcode/DerivedData/NBAPlayer-aeoygjukxhrzaxddvctkqcefsiql/Build/Intermediates/NBAPlayer.build/Debug/NBAPlayer.build/Objects-normal/x86_64/UnsortedStruct.o
/Users/noahheath/Library/Developer/Xcode/DerivedData/NBAPlayer-aeoygjukxhrzaxddvctkqcefsiql/Build/Intermediates/NBAPlayer.build/Debug/NBAPlayer.build/Objects-normal/x86_64/main.o
duplicate symbol __ZN9NFLplayer8ComparedES_ in:
/Users/noahheath/Library/Developer/Xcode/DerivedData/NBAPlayer-aeoygjukxhrzaxddvctkqcefsiql/Build/Intermediates/NBAPlayer.build/Debug/NBAPlayer.build/Objects-normal/x86_64/UnsortedStruct.o
/Users/noahheath/Library/Developer/Xcode/DerivedData/NBAPlayer-aeoygjukxhrzaxddvctkqcefsiql/Build/Intermediates/NBAPlayer.build/Debug/NBAPlayer.build/Objects-normal/x86_64/main.o
ld: 3 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
This is the script I have received from xcode and I cannot find the error to save my life. Can someone help me debug this? Forgive me if this isn't presented in the correct format. This is my first time using this website.
Here is my main code and here is the unsorted struct class
#include "NFL.h"
class UnsortedStruct
{
public:
UnsortedStruct();
int GetLength() const;
bool IsFull() const;
void EmptyList();
void InsertItem(NFLplayer nflplayers);
void DeleteItem(NFLplayer nflplayers);
void ResetList();
NFLplayer GetItem(NFLplayer nflPlayers, bool& found);
NFLplayer GetNextItem();
private:
int length;
int currentPos;
NFLplayer NFLlist[MAX_PLAYERS];
};
#include <string>
using namespace std;
const int MAX_PLAYERS = 10;
enum RelationType1 {LESS1, GREATER1, EQUAL1};
struct NFLplayer//describes the set of information for a NFL player.
{
string position, school, name, team;
RelationType1 Compared(NFLplayer);
NFLplayer();
};
NFLplayer::NFLplayer()
{
position=" ";
school=" ";
name=" ";
team=" ";
}
RelationType1 NFLplayer::Compared(NFLplayer players)
{
if(name < players.name)
return LESS1;
else if(name > players.name)
return GREATER1;
else
return EQUAL1;
}
You declared your constructor and your Compared function inside the .h file. Move them into a .cpp file and things should run smoothly.
A more insight on what's happening :
.h files are copy pasted into every object that is being compiled . So the main.o and UnsortedStruct.o will have the header file copy-pasted inside their object at preprocessor time.
You have two objects, and in each object you define the ::Compared and ::NFLPlayer functions implementation. You end up with two implementations of the same function, hence the duplicate symbol.
The .h files are meant to provide definitions for to-be-used structures, classes, functions (it's a forward declaration so to speak).
Implementation bodies are implemented in .cpp files , which in turn will be compiled then linked throughout the code after compilation.
When you see implementations in .h files, you will see that these are inside the class definition :
Class A
{
void foo() { // do something };
}
This is valid, because that function will become inlined.
However, declaring void foo ,then implementing it as A::foo() in the same file will be troublesome if the file is included as header in multiple compile units (objects).
Lots of errors from derived data, I assume you did an upgrade of Xcode?
Do the following steps in Xcode:
Product --> (hold down Alt key) --> Clean Build Folder
Product --> Clean Project
Window --> Organizer --> Delete derived data
Then build your project again.

Interface+Implementation in C++: code does not execute

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.
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.
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.