我是c ++的新学习者,当我在推荐的书籍Accelerated C ++中重复代码示例时,我遇到了麻烦: 这是目录结构:
./Project
|
+--- main.cpp
|
+--- lib/
|
+--- grade.cpp
|
+--- grade.h
+--- grade.cpp
|
+--- median.h
+--- median.cpp
|
+--- Student_info.h
+--- Student_info.cpp
的main.cpp
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <ios>
#include <stdexcept>
#include <string>
#include <vector>
#include "lib/median.h"
#include "lib/grade.h"
#include "lib/Student_info.h"
using namespace std;
int main(){
vector<Student_info> students;
Student_info record;
string::size_type maxlen=0;
while (read(cin,record)){
maxlen=max(maxlen,record.name.size());
students.push_back(record);
}
sort(students.begin(),students.end(),compare);
for(vector<Student_info>::size_type i=0;i!=students.size();++i) {
cout << students[i].name << string(maxlen + 1 - students[i].name.size(), ' ');
try{
double final_grade=grade(students[i]);
streamsize prec=cout.precision();
cout<<setprecision(3)<<final_grade<<setprecision(prec);
}catch(domain_error e){
cout<<e.what();
}
cout<<endl;
}
return 0;
}
grade.cpp
//
// Created by steafan on 2018/6/10.
//
#include "Student_info.h"
#include "median.h"
#include "grade.h"
#include <stdexcept>
#include <vector>
using std::domain_error;
using std::vector;
double grade(double midterm,double final,double homework){
return 0.2*midterm+0.4*final+0.4*homework;
}
/*
const means no change,& means a reference,not a copy of value
*/
double grade(double midterm,double final,const vector<double>& hw){
if(hw.size()==0){
throw domain_error("student has done no homework");
}
return grade(midterm,final,median(hw));
}
double grade(const Student_info& s){
return grade(s.midterm,s.final,s.homework);
}
grade.h
#ifndef UNTITLED_GRADE_H
#define UNTITLED_GRADE_H
#include <vector>
#include "Student_info.h"
double grade(double,double,double);
double grade(double,double,const std::vector<double>&);
double grade(const Student_info&);
#endif
Student_info.h
#ifndef UNTITLED_STUDENT_INFO_H
#define UNTITLED_STUDENT_INFO_H
#include <istream>
#include <string>
#include <vector>
struct Student_info{
std::string name;
double midterm,final;
std::vector<double> homework;
};
bool compare(const Student_info&,const Student_info&);
std::istream& read(std::istream&,Student_info&);
std::istream& read_hw(std::istream& , std::vector<double>&);
#endif //UNTITLED_STUDENT_INFO_H
Student_info.cpp
#include "Student_info.h"
#include <istream>
#include <string>
#include <vector>
using std::istream;
using std::vector;
bool compare(const Student_info& x,const Student_info& y){
return x.name<y.name;
}
istream& read(istream& is,Student_info& s){
is>>s.name>>s.midterm>>s.final;
read_hw(is,s.homework);
return is;
}
istream& read_hw(istream& in,vector<double>& hw){
if(in){
hw.clear(); //clear all the content in vector
double x;
while(in >> x){
hw.push_back(x);
}
in.clear(); //reset cin state
}
return in;
}
median.cpp
#include "median.h"
#include <vector>
#include <algorithm>
#include <stdexcept>
using std::domain_error;
using std::sort;
using std::vector;
inline double median(vector<double> vec){
typedef vector<double>::size_type vec_sz;
vec_sz size=vec.size();
if(size==0)
throw domain_error("meidan of an empty vector");
sort(vec.begin(),vec.end());
vec_sz mid=size/2;
return size%2==0?(vec[mid]+vec[mid-1])/2:vec[mid];
}
median.h
#ifndef chap5_MEDIAN_H
#define chap5_MEDIAN_H
#include <vector>
#include <algorithm>
#include <stdexcept>
double median(std::vector<double>);
#endif //UNTITLED_MEDIAN_H
我收到链接器错误,我无法修复:
Scanning dependencies of target STUDENT
[ 16%] Building CXX object grade-refactor/lib/CMakeFiles/STUDENT.dir/Student_info.cpp.o
[ 33%] Linking CXX static library libSTUDENT.a
/Library/Developer/CommandLineTools/usr/bin/ranlib: file: libSTUDENT.a(median.cpp.o) has no symbols
/Library/Developer/CommandLineTools/usr/bin/ranlib: file: libSTUDENT.a(median.cpp.o) has no symbols
[ 66%] Built target STUDENT
Scanning dependencies of target grade-refactor
[ 83%] Building CXX object grade-refactor/CMakeFiles/grade-refactor.dir/main.cpp.o
[100%] Linking CXX executable grade-refactor
Undefined symbols for architecture x86_64:
"median(std::__1::vector<double, std::__1::allocator<double> >)", referenced from:
grade(double, double, std::__1::vector<double, std::__1::allocator<double> > const&) in libSTUDENT.a(grade.cpp.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [grade-refactor/grade-refactor] Error 1
make[2]: *** [grade-refactor/CMakeFiles/grade-refactor.dir/all] Error 2
make[1]: *** [grade-refactor/CMakeFiles/grade-refactor.dir/rule] Error 2
make: *** [grade-refactor] Error 2
主文件夹的CMakeList.txt:
set(CMAKE_CXX_STANDARD 11)
include_directories(${PROJECT_SOURCE_DIR}/grade-refactor/lib)
add_subdirectory(lib)
ADD_EXECUTABLE(grade-refactor main.cpp )
target_link_libraries(grade-refactor STUDENT)
对于lib文件夹:
add_library(STUDENT grade.cpp median.cpp grade.h median.h Student_info.cpp Student_info.h)
我正在使用macos / Clion / Gcc组合,我做错了什么?我是C ++的新手,我们将不胜感激。