Hephaestus
Hephaestus

Reputation: 59

C++ Class file linking

I am still fairly new to C++, and I am having trouble making a class file and linking it to my main program and the implementation file.

Here is my specification file:

#ifndef BOOKCLASS_H
#define BOOKCLASS_H
#include<string>

using namespace std;

class Book
{
    private:
        string title;       //A string that holds the book’s title
        string author;      //A string that holds the book’s author
        string publisher;   //A string that holds the book’s publisher
        string isbn;        //A string that holds the book’s ISBN number
        double price;       //A double that holds the book’s price
        int year;           //An int that holds the year when the book was published
        int numInStock;     //An int that holds the number of copies of this book
    public:
        Book();                     //constuctor ---- will be overwritten by storeBook if getBookInfo operates properly
        void getBookInfo(Book &);   //gets the information for the book and calls storeBook within to store information to the variables
        void storeBook(string bookTitle, string authorName, string bookPublisher, string bookISBN, double bookPrice, int bookYear, int booksInStock);
        void displayBookInfo();     //Displays the contents of the BookClass member variables
        void checkOutBook();        //Subtracts 1 from the numInStock member variable, tests to make sure numInStock is not 0
        void returnBook()           //Adds 1 to the numInStock member variable
        { numInStock++; };
        string getTitle()           //Returns the value in title
        { return title; };
        int getNumInStock()         //Returns the value in numInStock
        { return numInStock; };
};
#endif // !BOOKCLASS_H

And here is the implementation file:

#include<iostream>
#include<string>
#include"BookClass.h"

using namespace std;


//*********************************************************************************************************************************************************************
//constuctor - this constuctor will assign generic values to the class, used primarily for troubleshooting and will be overwritten if program operates properly
//*********************************************************************************************************************************************************************
Book::Book()
{
    std::cout << "Made it into the constructor!\n\n";
    title = "Empty";
    author = "Empty";
    publisher = "Empty";
    isbn = "Empty";
    price = 0.00;
    year = 0000;
    numInStock = 0;
}

//*********************************************************************************************************************************************************************
//Asks the user to enter information for one book, then invokes member function storeBook to store the information in the BookClass variable.
//*********************************************************************************************************************************************************************
void Book::getBookInfo(Book &book)
{
    string bookTitle, authorName, bookPublisher, bookISBN;
    double bookPrice;
    int bookYear, booksInStock;

    cout << "Enter the book title: ";
    getline(cin, bookTitle);
    cout << "Enter the author: ";
    getline(cin, authorName);
    cout << "Enter the publisher: ";
    getline(cin, bookPublisher);
    cout << "Enter the ISBN-10 including dashes(ex. 0-00-000000-0): ";
    getline(cin, bookISBN);
    cout << "Enter the price: ";
    cin >> bookPrice;
    cout << "Enter the year: ";
    cin >> bookYear;
    cout << "Enter the quantity in stock: ";
    cin >> booksInStock;
    Book::storeBook(bookTitle, authorName, bookPublisher, bookISBN, bookPrice, bookYear, booksInStock);
}

//*********************************************************************************************************************************************************************
//Stores the values taken from the user input into the class variables
//*********************************************************************************************************************************************************************
void Book::storeBook(string bookTitle, string authorName, string bookPublisher, string bookISBN, double bookPrice, int bookYear, int booksInStock)
{
    title = bookTitle;
    author = authorName;
    publisher = bookPublisher;
    isbn = bookISBN;
    price = bookPrice;
    year = bookYear;
    numInStock = booksInStock;
}

//*********************************************************************************************************************************************************************
//Displays the contents of the BookClass member variables
//*********************************************************************************************************************************************************************
void Book::displayBookInfo()
{
    cout << "Title: "
         << title
         << "\nAuthor: "
         << author 
         << "\nPublisher: "
         << publisher
         << "\nISBN-10: "
         << isbn
         << "\nPrice: "
         << price
         << "\nYear: "
         << year
         << "\nQuantity in stock: "
         << numInStock;
}

//*********************************************************************************************************************************************************************
//Subtracts 1 from the numInStock member variable, tests to make sure numInStock is not 0
//*********************************************************************************************************************************************************************
void Book::checkOutBook()
{
    if(numInStock <= 0)
    {
        cout << "ERROR: All copies are checked out. Please select another title.\n";
        return;
    }
    else
        numInStock--;
}

And finally my main program:

#include"BookClass.h"
#include"BookMain.cpp"

using namespace std;

int main()
{
    Book book1;
    cout << "Before getBookInfo\n";
    getBookInfo(book1);
    cout << "\nAfter getBookInfo\n";

    system("pause");
    return 0;
}

I am sure I don't need to include a string class with each file, but if I don't I get many more errors. When I try to run it as is I get a compiler error stating:

error C2352: 'Book::storeBook' : illegal call of non-static member function

When I comment out the call for it (line 38 of the implementation file) and run again just to see if I can get into the getBookInfo function I get this:

1>Library Test Function.obj : error LNK2005: "public: void __thiscall Book::checkOutBook(void)" (?checkOutBook@Book@@QAEXXZ) already defined in BookMain.obj

1>Library Test Function.obj : error LNK2005: "public: void __thiscall Book::displayBookInfo(void)" (?displayBookInfo@Book@@QAEXXZ) already defined in BookMain.obj

1>Library Test Function.obj : error LNK2005: "void __cdecl getBookInfo(class Book &)" (?getBookInfo@@YAXAAVBook@@@Z) already defined in BookMain.obj

1>Library Test Function.obj : error LNK2005: "public: void __thiscall Book::storeBook(class std::basic_string,class std::allocator >,class std::basic_string,class std::allocator >,class std::basic_string,class std::allocator >,class std::basic_string,class std::allocator >,double,int,int)" (?storeBook@Book@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@000NHH@Z) already defined in BookMain.obj

I know the reference variable being passed into the getBookInfo function is not being used (the teacher wants the function to pass that argument), mostly because I'm not sure what to do with it, but I don't see that being the issue for my errors. Can someone please advise what I am doing wrong? Here is the part of the assignment including the format for getBookInfo function, should I separate it from the rest of the implementation file?

Member functions
• void storeBook(string bookTitle, string authorName, string bookPublisher, string bookISBN, double bookPrice, int bookYear, int booksInStock)
o Stores the parameters into the BookClass member variables
• void displayBookInfo() Displays the contents of the BookClass member variables
• void checkOutBook() Subtracts 1 from the numInStock member variable; tests to make sure numInStock is not 0
• void returnBook() Adds 1 to the numInStock member variable
• string getTitle() Returns the value in title
• int getNumInStock() Returns the value in numInStock
2. Create BookMain.cpp to test your BookClass.
Functions:
• void getBookInfo (BookClass &);
o Asks the user to enter information for one book, then invokes member function storeBook to store the information in the BookClass variable.
Test your class and function with a main program:

Thank you in advance for any advice!

Upvotes: 2

Views: 1163

Answers (3)

user3477273
user3477273

Reputation:

include "BookClass.h" in both, your main.cpp file and BookClass.cpp. Then compile all together. Let's say you're using g++

g++ -std=c++11 BookClass.cpp main.cpp -o file.out

Do not include your cpp file in your main.cpp file and the std namespace in your header file. Use the fully qualified path instead -> std::whatever

Upvotes: 0

boiler96
boiler96

Reputation: 1177

This code is calling storeBook() as if it were a static method:

Book::storeBook(...)

But the method is actually declared non-static:

class Book {
    ...
    void storeBook(...)

This is causing your error. Knowing the correct solution is somewhat trickier. Should the method be static or not? If the method operates on an existing Book instance, than it should be non-static, and you'll want to call it like this:

book.storeBook(...)

This will call the storeBook method on the instance of Book that was passed into the getBookInfo function as "book".

Based on the description of your problem, I think that's what you want.

Upvotes: 2

ncalmbeblpaicr0011
ncalmbeblpaicr0011

Reputation: 398

Book::storeBook() is a member-function. It is not a static function, so this is wrong:

Book::storeBook(bookTitle, authorName, bookPublisher, bookISBN, bookPrice, bookYear, booksInStock);

That can be changed to book.storeBook(...).

Do not #include"BookMain.cpp". That is causing your linking errors. You will most likely have to clean and rebuild.

Upvotes: 4

Related Questions