-2

I've got error "redefinition of class Book". Thats my code:

Book.cpp

#include "Book.h"

using namespace std;

class Book {
 string author, title;
public:
    Book()
    {
        cout<<"Book()"<<endl;
        author = "-";
        title = "-";
    }
    Book(const string& autor, const string& tytul)
    {
        cout<<"Book(const string& autor, const string& tytul)"<<endl;
        author = autor;
        title = tytul;
    }
    Book(string&& autor, string&& tytul)
    {
        cout<<"Book(Book&& autor, Book&& tytul)"<<endl;
        author=autor;
        title=tytul;
    }

    Book(const Book& other)
    :author(other.author),title(other.title)
    {
        cout<<"Book(const Book& other)"<<endl;
    }

    string GetAuthor()
    {
        return author;
    }
    string GetTitle()
    {
        return title;
    }
    void SetAuthor(const string &autor)
    {
        cout<<"Setter ze stalymi l-ref"<<endl;
        author=autor;
    }
    void SetTitle(const string &tytul)
    {
        cout<<"Setter ze stalymi l-ref"<<endl;
        title=tytul;
    }
    void SetAuthor(string &&autor)
    {
        cout<<"Setter r-ref"<<endl;
        author=autor;
    }
    void SetTitle(string &&tytul)
    {
        cout<<"Setter r-ref"<<endl;
        title=tytul;
    }

    //OPERATORY
    Book& operator=(const Book& right)
    {
        cout<<"Book& operator=(const Book& right)"<<endl;
        Book tmp = right;
        swap(author,tmp.author);
        swap(title,tmp.title);
        return *this;
    }

    Book& operator=(Book&& right)
    {
        cout<<"Book& operator=(Book&& right)"<<endl;
        swap(author,right.author);
        swap(title,right.title);
        return *this;
    }
};

Book.h

#include <string>
using namespace std;
class Book {
 string author, title;
public:
    Book();
    Book(const string& autor, const string& tytul);
    Book(string&& autor, string&& tytul);

    Book(const Book& other);

    string GetAuthor();
    string GetTitle();
    void SetAuthor(const string &autor);
    void SetTitle(const string &tytul);
    void SetAuthor(string &&autor);
    void SetTitle(string &&tytul);

    //OPERATORY
    Book& operator=(const Book& right);

    Book& operator=(Book&& right);
};

SOLUTIONS: after time, I can see few problems:

  • Never add using namespace std; in header files (namespace in header files)
  • cpp file should define methods from header file
  • declare class in header file and implement in cpp file
  • class template thats how class should looks like
  • when you want to define method from header file do this in proper way: ClassName::method_type method_name (){...}
Kawson
  • 138
  • 1
  • 10
  • 4
    Which [C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) told you that you should write function definitions in .cpp file like this? – Yksisarvinen Mar 12 '21 at 23:05
  • You can't have it both ways. Either declare the class is in a header file (recommended) **or** in the CPP file, not both. – Thomas Matthews Mar 12 '21 at 23:10
  • The duplicate have the same error, but for another and very different reason. Voting to repopen again. – Some programmer dude Mar 12 '21 at 23:11
  • On an unrelated note, `using namespace std;` is [a bad habit](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice), and doing it in a header file is considered not only a bad habit but actually wrong. – Some programmer dude Mar 12 '21 at 23:12
  • Oh, i missed that big stupid mistake... thanks now it works – Kawson Mar 12 '21 at 23:18

1 Answers1

3

The preprocessor which handles header files and the #include directive basically copy-pastes the header file into the place of the #include directive.

That means the compiler will see this in your source file:

class Book { ... };

class Book { ... };

You can't define a class multiple times like this.

Instead only define the class in the header file (and remember to add header include guards), and then the source file defines (implements) the functions only.

So beyond adding include guards, keep the header file as it is. Then change the source file to something similar to this:

#include "Book.h"

Book::Book()
{
    cout<<"Book()"<<endl;
    author = "-";
    title = "-";
}

// ...

std::string Book::GetAuthor()
{
    return author;
}

// ... And so on, doing the same with all other functions
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621