I'm writting a small project. I declare a class in the .hpp file and define it in a .cpp file, but when I use it, there is something error about linking.
DSMgr.hpp
#ifndef __DSMGR_HPP__
#define __DSMGR_HPP__
#include "predefine.hpp"
#include <fstream>
#include <string>
class DSMgr{
public:
DSMgr();
int OpenFile(std::string filename); // open the file speciafied by the filename
// and return an error code
int CloseFile(); // close the current file
bFrame ReadPage(const int& page_id); // gain data and return what it reads
int WritePage(const int& page_id, bFrame frm); // called when a page is taken out of buf
// return the number of bytes that be written
int Seek(const int& offset, const int& pos); // move the file pointer to the particular position
fstream& GetFile(); // get the currfile
void IncNumPages(); // increment the numPages
int GetNumPages() const; // return the numPages
void SetUse(const int& index, const int& use_bit); // maintain a global char array which keeps track of
// the use_bits of pages
int GetUse(const int& index) const; // return the use_bit of the particular page
private:
//FILE* currFile;
fstream currFile;
int numPages;
array<int, MAXPAGES> pages;
};
#endif
DSMgr.cpp
#include "../inc/dsmgr.hpp"
inline DSMgr::DSMgr() : numPages(0){ };
inline int DSMgr::OpenFile(std::string filename){
this->currFile.open(filename, ios::out | ios::in | ios::binary);
if(this->currFile.is_open()){
cout << "success: the file " << filename << " open successfully and reserve in the class DSMgr." << endl;
return 1;
}else{
cout << "error: can't open the file." << filename << endl;
abort();
}
}
inline int DSMgr::CloseFile(){
currFile.close();
if(currFile.is_open()){
cout << "error: can't close the current file." << endl;
abort();
}
return 1;
}
inline bFrame DSMgr::ReadPage(const int& page_id){
int pos = page_id * FRAMESIZE;
currFile.seekg(pos, ios::beg);
bFrame read_data;
currFile.read(read_data.field, FRAMESIZE);
return read_data;
}
inline int DSMgr::WritePage(const int& page_id, bFrame frm){
int pos = page_id * FRAMESIZE;
if(currFile.is_open()){
currFile.seekp(pos, ios::beg);
currFile.write(frm.field, strlen(frm.field));
}else{
cout << "error: the current file is not open, fail to write into." << endl;
abort();
}
}
inline int DSMgr::Seek(const int& offset, const int& pos){
if(this->currFile.is_open()){
this->currFile.seekp(pos + offset, ios::beg);
return 1;
}else{
cout << "error: the current file is not open so that can not seek file pointer." << endl;
abort();
}
}
#include <thread>
#include <chrono>
// for sleep_for()
inline fstream& DSMgr::GetFile(){
if(this->currFile.is_open()){
return this->currFile;
}else{
cout << "warnning: the current file is not open which may influence getting file." << endl;
std::this_thread::sleep_for(chrono::duration<int>(2));
}
}
inline void DSMgr::IncNumPages(){
++this->numPages;
}
inline int DSMgr::GetNumPages() const{
return this->numPages;
}
inline void DSMgr::SetUse(const int& index, const int& use_bit){
// assume that the id of pages mounts from zero
// convert use_bit into char
int use_bit_char = use_bit + 48;
use_bits[index] = char(use_bit_char);
}
inline int DSMgr::GetUse(const int& index) const{
int use_bit = int(use_bits[index]) - 48;
return use_bit;
}
predefine.hpp
#ifndef __PREDEFINE_HPP__
#define __PREDEFINE_HPP__
#include <array>
#include <iostream>
using namespace std;
// a block called page in physical memory and frame in buffer.
#define MAXPAGES 50000
#define FRAMESIZE 4096
struct bFrame
{
char field[FRAMESIZE];
};
#define DEFBUFSIZE 1024
extern array<bFrame*, DEFBUFSIZE> buf; // the buf consists of an array of frame
// Buffer Control Blocks
struct BCB{
BCB();
int page_id;
int frame_id;
int latch;
int count;
int dirty;
BCB* next;
};
// the arrays below are defined in the class BMgr
// extern array<int, DEFBUFSIZE> hTable; // frame_id -> page_id
// extern array<BCB, DEFBUFSIZE> hTable_b; // page_id -> BCB
inline const int HashCov(const int& id){ // compute hash value
return (id % DEFBUFSIZE);
}
// double-linked list to manage least recently use list
// assign the head of the list to 'MRU' interface,
// while the tail is 'LRU' interface that should be chosen to replace
#include <list>
static list<int> LM;
// a string that keeps use_bits of pages
static char use_bits[MAXPAGES];
extern int ext;
#endif
testt.cpp
#include "../inc/dsmgr.hpp"
int main(){
DSMgr _dd = DSMgr();
return 0;
}
And the following is error information.
/usr/bin/clang++ -std=c++14 -fcolor-diagnostics -fansi-escape-codes -g /Users/luzijian/Documents/Document/Ustc/FirstTerm/AdvancedDatabaseSystem/lab/src/*.cpp -o /Users/luzijian/Documents/Document/Ustc/FirstTerm/AdvancedDatabaseSystem/lab/src/../bin/testt
/Users/luzijian/Documents/Document/Ustc/FirstTerm/AdvancedDatabaseSystem/lab/src/dsmgr.cpp:42:1: warning: non-void function does not return a value in all control paths [-Wreturn-type]
}
/Users/luzijian/Documents/Document/Ustc/FirstTerm/AdvancedDatabaseSystem/lab/src/dsmgr.cpp:64:1: warning: non-void function does not return a value in all control paths [-Wreturn-type]
}
2 warnings generated.
Undefined symbols for architecture arm64:
"DSMgr::DSMgr()", referenced from:
_main in testt-a26be3.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
However, when I try to define another class in a test file, it runs successfully.
lru.hpp
#ifndef __LRU_HPP__
#define __LRU_HPP__
class LRU{
public:
int replace(const int& frame_id); // move a frame to the first place if it is not
int add(const int& frame_id); // add a new frame into the list
int select(const int& pos); // select a victim frame and remove it
// the second parameter is to control which frame to return
};
#endif
lru.cpp
#include "../inc/lru.hpp"
#include "../inc/predefine.hpp"
inline int LRU::replace(const int& frame_id){
if(frame_id != LM.front()){
auto pos = find(LM.begin(), LM.end(), frame_id);
int item = *pos;
LM.erase(pos);
LM.push_front(item);
}
return 1;
}
inline int LRU::add(const int& frame_id){
// compare the size of LM list with DEFBUFSIZE
if(DEFBUFSIZE <= LM.size()){
cout << "error: the capacity of LM list is full, can not add a new frame." << endl;
return 0;
}else{
LM.push_front(frame_id);
}
return 1;
}
inline int LRU::select(const int& offset){
auto pos = LM.end();
advance(pos, -offset-1);
return *pos;
}
testt.cpp
#include "../inc/lru.hpp"
int main(){
LRU _ll = LRU();
return 0;
}
When I define the LRU
class in the testt.cpp
file and compile it, there is no error.
Is there anyone can help me solve this problem.