C++oop多个链接器错误

C++ oop multiple linker errors

本文关键字:错误 链接 C++oop      更新时间:2023-10-16

我在头文件中定义了一个Student类和一个Name类,函数实现在cpp文件中。在使用Visual Studio 2015进行编译时,我收到以下错误:

Severity    Code    Description Project File    Line
Error   LNK2019 unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Student const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABVStudent@@@Z) referenced in function _main    3512-lab8   c:UsersTessdocumentsvisual studio 2015Projects3512-lab83512-lab8main.obj    1
Error   LNK2019 unresolved external symbol "class std::basic_istream<char,struct std::char_traits<char> > & __cdecl operator>>(class std::basic_istream<char,struct std::char_traits<char> > &,class Student &)" (??5@YAAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAV01@AAVStudent@@@Z) referenced in function _main  3512-lab8   c:UsersTessdocumentsvisual studio 2015Projects3512-lab83512-lab8main.obj    1
Error   LNK1120 2 unresolved externals  3512-lab8   c:userstessdocumentsvisual studio 2015Projects3512-lab8Debug3512-lab8.exe   1

这是我的文件

名称.h

#include <string>
#ifndef NAME_H
#define NAME_H
class Name {
public:
    Name() {}
    Name(const std::string& first, const std::string& last)   :first_(toLowerCase(first)), last_(toLowerCase(last)) {}
    std::string toLowerCase(const std::string& s);
    friend std::istream& operator>>(std::istream& is, Name& n);
    friend std::ostream& operator<<(std::ostream& os, const Name& n);
    friend bool isValidName(const Name& n);
private:
    std::string first_;
    std::string last_;
    static bool isValidName(const Name& n);
};
#endif

学生.h

#include "Name.h"
#include <string>
#ifndef STUDENT_H
#define STUDENT_H
class Student {
public:
    Student(){}
    explicit Student(const Name& name, const std::string& id = "A11111111") :id_(id), name_(name) {
    if (!isValidId(id_)) {
        throw "invalid id";
    }
    else if (!isValidName(name_)) {
        throw "invalid name";
    }
}
    virtual ~Student(){}
    friend std::ostream& operator<<(std::ostream& os, const Student& s);
    friend std::istream& operator>>(std::istream& is, Student& s);
    friend bool operator<(const Student& lhs, const Student& rhs);
private:
    std::string id_;
    Name name_;
    static bool isValidId(const std::string& id);
};
#endif

姓名.cpp

#include "Name.h"
std::istream& operator>>(std::istream& is, Name& n) {
    return is >> n.first_ >> n.last_;
}
std::ostream& operator<<(std::ostream& os, const Name& n) {
    return os << n.first_ << " " << n.last_;
}
std::string Name::toLowerCase(const std::string& s) {
    std::string str = s;
    for (std::string::size_type i = 0; i < s.size(); i++) {
        tolower(str[i]);
    }
    return str;
}
bool Name::isValidName(const Name & n){
    std::string::size_type i;
    std::string::size_type first_size = n.first_.size();
    std::string::size_type last_size = n.last_.size();
    if (first_size == 0 || last_size == 0) {
        return false;
    }
    for (i = 0; i < first_size; ++i) {
        if (!isalpha(n.first_[i])) {
            return false;
        }
    }
    for (i = 0; i < last_size; ++i) {
        if (!isalpha(n.last_[i])) {
            return false;
        }
    }
    return true;
}

学生.cpp

#include "Student.h"
#define SID_LENGTH 9
bool operator<(const Student& lhs, const Student& rhs) {
    return lhs.id_ < rhs.id_;
}
bool Student::isValidId(const std::string & id){
    std::string::size_type i = 0;
    if (id.length() == SID_LENGTH) {
        if (id[i] == 'A' || id[i] == 'a') {
            for (i = 1; i < id.size(); i++) {
                if (!isdigit(id[i])) {
                    return false;
                } 
            }
            return true;
        }
    }
    return false;
}

主要.cpp

#include "Student.h"
#include <iostream>
#include <map>
int main() {
    std::map<Student, int> m;
    Student s;
    int score;
    while (std::cin >> s >> score) {
        m[s] += score;
    }
    for (const auto& it : m) {
        std::cout << it.first << "" << it.second << std::endl;
    }
}

main()文件中的#include .h文件,而不是.cpp文件

您已经为Student类声明了一个重载的operator<<operator>>,但从未在.cpp文件中定义过它们。我想这就是你看到的错误。

我不确定在编辑之前它是什么样子的,但您确实需要在Name.h文件(以及Main.cpp文件)中包含<iostream>

相关文章: