Доброго времени суток. Изучаю C++.
В MS Visual Studio 2012 создал пустой C++ проект. В группу "Source Files" добавил два файла:
Файл Book.cpp:
Код | #include<cstring>
namespace ab{ class Book{ static int booksCount; char name[50]; char author[50]; public: Book(char *name, char *author); ~Book(); char *GetName(){return name;} void SetName(const char *name){if (!*name) strcpy(this->name, name);} char *GetAuthor(){return author;} void SetAuthor(const char *author){if (!*author) strcpy(this->author, author);} static int GetBooksCount(); };
int Book::booksCount; int Book::GetBooksCount(){ return Book::booksCount;}
Book::Book(char *name, char *author){ SetName(name); SetAuthor(author); ++Book::booksCount; }
Book::~Book(){ --Book::booksCount; } }
|
Файл main.cpp:
Код | #include<iostream> #include"Book.cpp"
int main(){ ab::Book book("Ivan", "Ivanov"); ab::Book book2("Oleg", "Olegovich"); ab::Book *p = new ab::Book("Sergey", "Sergeevich"); std::cout << "Books count: " << ab::Book::GetBooksCount() << std::endl; delete p; std::cout << "Books count: " << ab::Book::GetBooksCount() << std::endl; return 0; }
|
Однако скомпилировать код не удаётся:
Цитата(Текст ошибок) | Error 5 error LNK2005: "public: __thiscall ab::Book::Book(char *,char *)" (??0Book@ab@@QAE@PAD0@Z) already defined in Book.obj C:\Users\bushm_000\Documents\Visual Studio 2012\Projects\@Projects\Current Projects\CppClasses\main.obj CppClasses Error 6 error LNK2005: "public: __thiscall ab::Book::~Book(void)" (??1Book@ab@@QAE@XZ) already defined in Book.obj C:\Users\bushm_000\Documents\Visual Studio 2012\Projects\@Projects\Current Projects\CppClasses\main.obj CppClasses Error 7 error LNK2005: "public: static int __cdecl ab::Book::GetBooksCount(void)" (?GetBooksCount@Book@ab@@SAHXZ) already defined in Book.obj C:\Users\bushm_000\Documents\Visual Studio 2012\Projects\@Projects\Current Projects\CppClasses\main.obj CppClasses Error 8 error LNK2005: "private: static int ab::Book::booksCount" (?booksCount@Book@ab@@0HA) already defined in Book.obj C:\Users\bushm_000\Documents\Visual Studio 2012\Projects\@Projects\Current Projects\CppClasses\main.obj CppClasses Error 9 error LNK1169: one or more multiply defined symbols found C:\Users\bushm_000\Documents\Visual Studio 2012\Projects\@Projects\Current Projects\CppClasses\Debug\CppClasses.exe CppClasses
|
Если я класс Book перепишу, сделав все функции подставляемыми (inline), то количество ошибок значительно уменьшается:
Код | #include<cstring>
namespace ab{ class Book{ static int booksCount; char name[50]; char author[50]; public: Book(char *name, char *author){ SetName(name); SetAuthor(author); ++Book::booksCount; } ~Book(){ --Book::booksCount; } char *GetName(){return name;} void SetName(const char *name){if (!*name) strcpy(this->name, name);} char *GetAuthor(){return author;} void SetAuthor(const char *author){if (!*author) strcpy(this->author, author);} static int GetBooksCount(){ return Book::booksCount;} };
int Book::booksCount; }
|
Ошибки компиляции:
Цитата | Error 5 error LNK2005: "private: static int ab::Book::booksCount" (?booksCount@Book@ab@@0HA) already defined in Book.obj C:\Users\bushm_000\Documents\Visual Studio 2012\Projects\@Projects\Current Projects\CppClasses\main.obj CppClasses Error 6 error LNK1169: one or more multiply defined symbols found C:\Users\bushm_000\Documents\Visual Studio 2012\Projects\@Projects\Current Projects\CppClasses\Debug\CppClasses.exe 1 1 CppClasses
|
Но Book::booksCount - это статическая переменная... Хочешь-не хочешь, а определять её вне класса придётся. Если я закомментирую определение, то вылезают ошибки:
Цитата | Error 5 error LNK2001: unresolved external symbol "private: static int ab::Book::booksCount" (?booksCount@Book@ab@@0HA) C:\Users\bushm_000\Documents\Visual Studio 2012\Projects\@Projects\Current Projects\CppClasses\main.obj CppClasses Error 6 error LNK1120: 1 unresolved externals C:\Users\bushm_000\Documents\Visual Studio 2012\Projects\@Projects\Current Projects\CppClasses\Debug\CppClasses.exe 1 1 CppClasses
|
В чём проблема? Почему мне приходится переписывать функции как inline? Как этого избежать, если мне это не надо? И почему так и остаётся проблема со статическим полем?
|