C ++ Новичок - Ошибки Переопределения Заголовка, Связывая Ошибки - PullRequest
0 голосов
/ 19 июля 2011

Я очень плохо знаком с C ++, я пытаюсь закончить университетскую работу. Я строю свою программу на C ++ в Visual Studio 2010. Я вылил код и не могу понять, почему он не работает. Ниже приведен весь код моего проекта. Извините, что мне пришлось все это опубликовать, но я не знаю, в чем проблема.

employee.h

#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include <string>

using namespace std;

class Employee
{
public:
    int empNumber;

    string getName();
    int getId();
    float getBaseSalary();
    virtual string getTitle();
    virtual int getNumTaskCompleted();
    virtual float getGrossSalary();
    virtual float getBonus();
    virtual void setEmployeeDetails();
};
#endif

employee.cpp

#include <string>
#include <iostream>

using namespace std;

class Employee
{
private:
    string name;
    int id;
    float salary;

public:
    string getName()
    {
        return this->name;
    }

    int getId()
    {
        return this->id;
    }

    float getBaseSalary()
    {
        return this->salary;
    }

    void setEmployeeDetails()
    {
        cout << "Enter employee name (no spaces): ";
        cin >> this->name;
        cout << "Enter employee id (numeric): ";
        cin >> this->id;
        cout << "Enter employee salary: ";
        cin >> this->salary;
    }
};

projectManager.h

#ifndef PROJECT_MANAGER_H
#define PROJECT_MANAGER_H
#include <string>
#include "employee.h"

using namespace std;

class ProjectManager : public Employee
{
public:
    string getTitle();
    int getNumTaskCompleted();
    float getGrossSalary();
    float getBonus();
    void setBonus(float bonus);
    void setEmployeeDetails();
};
#endif

projectManager.cpp

#include <string>
#include <iostream>
#include "employee.h"

using namespace std;

class ProjectManager : public Employee
{
private:
    int numTaskCompleted;
    float bonus;

public:
    string getTitle()
    {
        return "Manager";
    }

    int getNumTaskCompleted()
    {
        return this->numTaskCompleted;
    }

    float getGrossSalary()
    {
        return this->getBaseSalary() + this->bonus;
    }

    float getBonus()
    {
        return this->bonus;
    }

    void setBonus(float bonus)
    {
        this->bonus = bonus;
    }

    void setEmployeeDetails()
    {
        Employee::setEmployeeDetails();

        cout << "Enter tasks completed (numeric): ";
        cin >> this->numTaskCompleted;

        if (numTaskCompleted >= 5)
            this->setBonus(10000.00f);
    }
};

softwareEngineer.h

#ifndef SOFTWARE_ENGINEER_H
#define SOFTWARE_ENGINEER_H
#include <string>
#include "employee.h"

using namespace std;

class SoftwareEngineer : public Employee
{
public:
    string getTitle();
    int getNumTaskCompleted();
    float getGrossSalary();
    float getBonus();
    void setBonus(float bonus);
    void setEmployeeDetails();
};
#endif

softwareEngineer.cpp

#include <string>
#include <iostream>
#include "employee.h"

using namespace std;
class SoftwareEngineer : public Employee
{
private:
    int numTaskCompleted;
    float bonus;

public:
    string getTitle()
    {
        return "Engineer";
    }

    int getNumTaskCompleted()
    {
        return this->numTaskCompleted;
    }

    float getGrossSalary()
    {
        return this->getBaseSalary() + this->bonus;
    }

    float getBonus()
    {
        return this->bonus;
    }

    void setBonus(float bonus)
    {
        this->bonus = bonus;
    }

    void setEmployeeDetails()
    {
        Employee::setEmployeeDetails();

        cout << "Enter tasks completed (numeric): ";
        cin >> this->numTaskCompleted;

        if (numTaskCompleted >= 30)
            this->setBonus(5000.00f);
    }
};

program.cpp

#include <string>
#include <iostream>
#include <iomanip>

#include "employee.h"
#include "projectManager.h"
#include "softwareEngineer.h"

using namespace std;

Employee *_employees[4];

int main()
{
    for (int employeeIndex = 0; employeeIndex < 4; employeeIndex++)
    {
        Employee *CurrentEmployee = new Employee();
        CurrentEmployee->setEmployeeDetails();
        _employees[employeeIndex] = CurrentEmployee;
    }

    cout
        << setw(12) << "Employee" 
        << setw(5) << "Id"
        << setw(15) << "Employee"
        << setw(7) << "Task" 
        << setw(10) << "Base"
        << setw(13) << "Bonus"
        << setw(12) << "Gross" << endl;


    cout
        << setw(11) << "Title" 
        << setw(9) << "Number" 
        << setw(10) << "Name"
        << setw(12) << "Completed"
        << setw(8) << "Salary" 
        << setw(15) << "Entitlement"
        << setw(9) << "Salary" << endl;

    for (int employeeIndex = 0; employeeIndex < 4; employeeIndex++)
    {
        cout
            << setw(12) << _employees[employeeIndex]->getTitle()
            << setw(8)  << _employees[employeeIndex]->getId()
            << setw(13) << _employees[employeeIndex]->getName()  
            << setw(5)  << _employees[employeeIndex]->getNumTaskCompleted()
            << setw(13) << _employees[employeeIndex]->getBaseSalary()
            << setw(14) << _employees[employeeIndex]->getBonus()
            << setw(11) << _employees[employeeIndex]->getGrossSalary() << endl;
    }

    return 0;
}

Когда я пытаюсь отладить эту программу, я получаю сообщение об ошибке сборки. Это ошибки сборки, которые я получаю.

Ошибка 1, ошибка LNK2019: неразрешенный внешний символ "public: int ссылка __thiscall Employee :: getId (void) "(? getId @ Employee @@ QAEHXZ) в функции _main E: \ C ++ Назначения \ assignment_7 \ assignment_7 \ program.obj assignment_7 Ошибка 3 ошибка LNK2019: неразрешенный внешний символ "public: float __thiscall Employee :: getBaseSalary (void) " (? getBaseSalary @ Employee @@ QAEMXZ) ссылка на функцию _main E: \ C ++ Назначения \ assignment_7 \ assignment_7 \ program.obj assignment_7 Ошибка 2 ошибка LNK2019: неразрешенный внешний символ "public: class станд :: basic_string, класс std :: allocator> __thiscall Employee :: getName (void) " (? GetName @ Сотрудник @@ QAE? А.В.? $ Basic_string @ DU? $ Char_traits @ D @ станд @@ V? $ Распределитель @ D @ 2 @@ станд @@ XZ) упоминается в функции _main E: \ C ++ Назначения \ assignment_7 \ assignment_7 \ program.obj assignment_7 Ошибка 8 ошибка LNK2001: неразрешенный внешний символ "public: virtual void __thiscall Employee :: setEmployeeDetails (void) " (? setEmployeeDetails @ Employee @@ UAEXXZ) E: \ C ++ Назначения \ assignment_7 \ assignment_7 \ program.obj assignment_7 Ошибка 5 ошибка LNK2001: неразрешенный внешний символ "public: virtual int __thiscall Employee :: getNumTaskCompleted (void) " (? getNumTaskCompleted @ Employee @@ UAEHXZ) E: \ C ++ Назначения \ assignment_7 \ assignment_7 \ program.obj assignment_7 Ошибка 6 ошибка LNK2001: неразрешенный внешний символ "public: virtual float __thiscall Employee :: getGrossSalary (void) " (? getGrossSalary @ Employee @@ UAEMXZ) E: \ C ++ Назначения \ assignment_7 \ assignment_7 \ program.obj assignment_7 Ошибка 7 Ошибка LNK2001: неразрешенный внешний символ "public: virtual float __thiscall Employee :: getBonus (void) " (? getBonus @ Employee @@ UAEMXZ) E: \ C ++

Я понятия не имею, что означают эти ошибки. Я просмотрел коды ошибок, но не смог получить от них никакой информации, которая помогла бы мне понять, что я делаю неправильно.

Может кто-нибудь понять, что не так? Спасибо!

Ответы [ 5 ]

4 голосов
/ 19 июля 2011

Это ошибки компоновщика ... после того, как компилятор завершит компиляцию кода C ++ в объектные файлы, компоновщик затем "связывает" эти файлы вместе в исполняемый файл.Однако компоновщик говорит, что он не может найти функции для связывания, которые вызываются в вашей main функции.

Большая проблема, которую я вижу сейчас, состоит в том, что вы объявили свои классывнутри ваших заголовочных файлов, но затем вы повторно объявляете их в своих .cpp файлах.Это вызовет проблемы. Объявите ваши классы в ваших заголовочных файлах (как вы это сделали), но определите ваши функции классов в ваших .cpp файлах (вы заново делаете объявление в вашем .cppфайлы вместе с определением).

1 голос
/ 19 июля 2011

Как и все остальные, вы объявляли одни и те же классы несколько раз в разных файлах.Как правило, используйте заголовочные файлы (расширение .h) для описания классов и исходные файлы (расширение .cpp) для определений.Размещать их в обоих местах не нужно и неправильно.

1 голос
/ 19 июля 2011

у вас есть несколько определений class Employee в employee.h и employee.cpp. Объявите класс Employee в employee.h и определите его методы в employee.cpp

0 голосов
/ 19 июля 2011

От макушки головы ... попробуйте это:

employee.h:

#ifndef EMPLOYEE_H
#define EMPLOYEE_H

#include <string>

class Employee
{
private:
    std::string name;
    int id;
    float salary;

public:
    int empNumber;

    std::string getName();

    // Etc...

};
#endif

employee.cpp:

#include "employee.h"

std::string Employee::getName()
{
    return name;
}

// Etc...

Кстати, избегайте using namespace в заголовках - это может «загрязнить» непреднамеренно большую часть кода. Делайте это только в CPP.

0 голосов
/ 19 июля 2011

Вам не нужно включать объявление класса в заголовочные и исходные файлы.Реализация должна выглядеть следующим образом:

employee.cpp

#include <string>
#include <iostream>

using namespace std;

string Employee::getName()
{
    return this->name;
}
...