我正在做一個小專案來提高我在 C 中的 OOP 技能 - 該專案只是一個簡單的書籍集合,有點像家庭圖書館,書籍可以存盤在虛擬書架中,分組到具有各自名稱的更大書架等,每本書都有自己的ID,是一個正整數。我試圖創建一個用戶定義的類解構式,我想將解構式的實作移動到源檔案,遵循將比一行長的實作移動更長的規則從.hpp檔案移動到.cpp檔案以幫助構建養成更好的優化更快的代碼的習慣(當然在這個例子中它不會有幫助,但我只是想找到解決遇到的問題的方法,而不是在以后掙扎)。
但是,在嘗試編譯我的代碼時,出現以下錯誤:
c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/bookshelf.dir/objects.a(bookshelf.cpp.obj): in function `void std::_Destroy<Book>(Book*)':
c:/mingw/include/c /9.2.0/bits/stl_construct.h:98: undefined reference to `Book::~Book()'
collect2.exe: error: ld returned 1 exit status
make.exe[2]: *** [CMakeFiles/bookshelf.dir/build.make:101: bookshelf.exe] Error 1
make.exe[1]: *** [CMakeFiles/Makefile2:139: CMakeFiles/bookshelf.dir/all] Error 2
make.exe: *** [Makefile:111: all] Error 2
The terminal process "C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe -Command cmake --build Build" terminated with exit code: 1.
我使用 Visual Studio Code 并使用 MinGW64 編譯器編譯我的代碼,在 Windows 11 上作業,并且我的專案使用以下 CMakeLists 檔案設定:
cmake_minimum_required(VERSION 3.0.0)
project(Book VERSION 0.1.0)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# include(GoogleTest)
# enable_testing()
add_executable(main main.cpp)
add_executable(book src/book.cpp include/bookshelf.hpp include/book.hpp include/types.hpp include/helpers.hpp)
add_executable(bookshelf src/bookshelf.cpp include/bookshelf.hpp)
# add_executable(library src/library.cpp include/library.hpp)
add_compile_options(-Werror -Wextra -Wall -Wconversion -Wpedantic -pedantic-errors -unused-variable)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
include_directories(
include
src
)
這是頭檔案和源檔案的代碼: book.cpp
#include <cstdlib>
#include <iostream>
#include <set>
#include "book.hpp"
#include "helpers.hpp"
Book::~Book(){
ids.erase(book_id_);
freed_ids.insert(book_id_);
//@TODO: To be implemented - destroy the object, not only deal with the book's ID!
};
Book::Book(Title title, Author author) : title_(title), author_(author){
if(!freed_ids.empty()){
book_id_ = *(freed_ids.begin());
}
else if(freed_ids.empty() && !ids.empty()){
book_id_ = *(ids.end());
}
else{
book_id_ = 0;
}
ids.insert(book_id_);
};
int main(){
std::cout << "Hello, from book.cpp!" << std::endl;
return EXIT_SUCCESS;
}
書.hpp
#ifndef book
#define book
#include "types.hpp"
#include "helpers.hpp"
/*
Class represeting a book as en entry in a collection of books.
@param author_ Author of the book.
@param title_ Title of the book.
@param book_id_ ID of a book.
*/
class Book{
private:
Author author_;
Title title_;
BookID book_id_;
public:
Book(Title title, Author author);
/*Get the title of the book.
@TODO: To be moved into a new class Library*/
Title get_title() const {return title_;}
/*Get the author of the book.
@TODO: To be moved into a new class Library*/
Author get_author() const {return author_;}
/*Get the ID number of the book.
@TODO: To be moved into a new class Library*/
BookID get_id() const {return book_id_;}
~Book();
};
#endif
只需將解構式的主體移動到.hpp檔案,代碼就可以很好地編譯,但這并不能解決我的問題。.cpp檔案中定義的建構式作業得很好,我不明白為什么解構式不起作用。
在此先感謝您的幫助!
PS如果我的代碼中有些東西沒有意義并且只是愚蠢的,也請隨時告訴我,非常感謝這樣的英特爾。
@user17732522 I have applied the changes you suggested me in the answer below and the problem with the destructor does not occur now, but instead I get errors stating that there are multiple definitions of std::set objects I used to store IDs and names - they look like this:
c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe:
CMakeFiles/main.dir/objects.a(bookshelf.cpp.obj):C:/Users/Darek/Desktop/projects/myLibrary/include/helpers.hpp:9: multiple definition of `ids';
CMakeFiles/main.dir/objects.a(book.cpp.obj):C:/Users/Darek/Desktop/projects/myLibrary/include/helpers.hpp:9: first defined here
And two similar errors are present along with that one, except they refer to freed_ids and shelf_names std::set-type objects.
Here is the helpers.hpp file, not very complicated:
#ifndef HELPERS_HEADER_GUARD
#define HELPERS_HEADER_GUARD
#include <cstdlib>
#include <set>
#include <utility>
#include "types.hpp"
std::set<BookID> ids;
std::set<BookID> freed_ids;
std::set<ShelfName> shelf_names;
#endif
And the bookshelf.cpp file also present in the error message:
#include <iostream>
#include <vector>
#include <exception>
#include <algorithm>
#include "bookshelf.hpp"
Bookshelf::Bookshelf(ShelfName shelf_name){
if(std::find(shelf_names.begin(), shelf_names.end(), shelf_name) != shelf_names.end()){
throw(std::invalid_argument("A bookshelf with the given name already exists."));
}
else{
shelf_name_ = shelf_name;
// content_ = {};
}
}
uj5u.com熱心網友回復:
您將程式拆分為多個:
add_executable(main main.cpp)
add_executable(book src/book.cpp include/bookshelf.hpp include/book.hpp include/types.hpp include/helpers.hpp)
add_executable(bookshelf src/bookshelf.cpp include/bookshelf.hpp)
您只需要一個可執行檔案。此外,頭檔案不屬于那里:
add_executable(main main.cpp src/book.cpp src/bookshelf.cpp)
(順便說一句。為什么main.cpp不在src?)
另一方面include_directories應該只包括include目錄:
include_directories(
include
)
undefined reference 錯誤的原因是,使用您的原始配置,CMake 將創建三個獨立的程式。只考慮這個:
add_executable(bookshelf src/bookshelf.cpp include/bookshelf.hpp)
它將通過編譯來構建src/bookshelf.cpp,而不是使用src/book.cpp. (這些.hpp檔案在這里應該無關緊要,但仍然不屬于命令。)。
所以bookshelf.cpp可能包含一些型別的(成員)變數Book。為了使用這個變數,程式需要知道如何構造和銷毀該型別的變數。換句話說,它需要有 的建構式和解構式的定義Book。但兩者的定義都只在檔案中book.cpp,不包括在本次程式編譯中。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/401861.html
標籤:c oop destructor
上一篇:UICollectionViewCompositionalLayout的可重用標頭
下一篇:根據屬性及其值過濾物件串列
