Ошибка во время компиляции Vscode — Ошибка связывания?

#c

Вопрос:

У меня возникла проблема при попытке скомпилировать мой проект. Это дает мне неопределенные ошибки. Все исследования в Интернете дают мне предположения о том, что компилятор неправильно связывает мои файлы. Вот мой код и ошибки, связанные с ним.

Киномонстр.ч

 #ifndef MonsterMainClass_h
#define MonsterMainClass_h

class MovieMonster
{
    protected:
    
    int Power = 0; // The level of power of the monster
    double Health = 0; // The number of health points 
    bool intellect = false; // Whether the monster is smart
    bool XtrSize = false; //Does the monster have superduper size?

    public:

    MovieMonster(int power = 0, double health = 0, bool intellect = false, bool xtrSize = false); // Constructor
    MovieMonster(); //Default Constructor
   
    ~MovieMonster(); // Destructor
    void setPower(int);// sets the power of the monster
    void setHealth(double);//sets the health of the monster
    void setXtrSize(bool); //sets whter the monster is Xtra in the size department
    void setIntellect(bool);//sets whter the monster is intelligent or a dummy!
    void print() const; // prints the monster values
};

#endif
 

MovieMonster.cpp

 #include <iostream> 
#include <iomanip>
#include "MonsterMainClass.h"
  
using namespace std;

int p = 0;
double h = 0;
bool xtr = false;
bool smrt = false;

MovieMonster(p, h, xtr, smrt);

void MovieMonster::setPower(int p) // sets the power of the monster
{
    Power = p;
}

void MovieMonster::setHealth(double h) // set health function
{
    Health = h;
}

void MovieMonster::setXtrSize(bool xtr) // sets the size of monster Large or Small
{
    XtrSize = xtr;
}

void MovieMonster::setIntellect(bool smrt) // sets whether the monster is a dummy or sophisticated
{
    intellect = smrt;
}

void MovieMonster::print() const // prints the monsters characteristics
{
    for (size_t i = 0; i < 25; i  )
    {
        cout << "*";
    }
    cout << "Monster Power: " << Power << endl;
    cout << "Health: " << Health << endl;
    cout << "Xtr Size: " << XtrSize << endl;
    cout << "Intellect: " << intellect << endl;
    for (size_t i = 0; i < 25; i  )
    {
        cout << "*";
    }  

}

MovieMonster::~MovieMonster() {}
 

CreateMonster.cpp

 #include <iostream> 
#include "MonsterMainClass.h"
  
using namespace std;

int main()
{
    MovieMonster Renee;

    Renee.setHealth(.50);
    Renee.setIntellect(true);
    Renee.setXtrSize(true);
    Renee.setPower(100);
    Renee.print();

    return 0;
}
 

Я использую компьютер с Windows и код VS, как показано ниже:

 Version: 1.60.2 (user setup)
Commit: 7f6ab5485bbc008386c4386d08766667e155244e
Date: 2021-09-22T12:00:31.514Z
Electron: 13.1.8
Chrome: 91.0.4472.164
Node.js: 14.16.0
V8: 9.1.269.39-electron.0
OS: Windows_NT x64 10.0.19043
 

Что странно, так это то, что когда я пытаюсь собрать примеры из книги, я получаю те же ошибки. Любое руководство будет высоко оценено!

Обновленные ошибки:

 PS C:Userscdieckert-la.vscodeCOSC1436Prog 2 Code testMovie Monster Class> g   .CreateMonsters.cpp
.CreateMonsters.cpp: In function 'int main()':
.CreateMonsters.cpp:13:18: error: call of overloaded 'MovieMonster()' is ambiguous
     MovieMonster Monster;
                  ^~~~~~~
In file included from .CreateMonsters.cpp:3:
.MonsterMainClass.h:20:5: note: candidate: 'MovieMonster::MovieMonster()'
     MovieMonster(); //Default Constructor
     ^~~~~~~~~~~~
.MonsterMainClass.h:19:5: note: candidate: 'MovieMonster::MovieMonster(int, double, bool, bool)'
     MovieMonster(int power = 0, double health = 0, bool intellect = false, bool xtrSize = false); // Constructor
     ^~~~~~~~~~~~
 

Комментарии:

1. Вам не хватает реализации для деструктора. Добавьте MovieMonster::~MovieMonster() {} в свой MovieMonster.cpp Кстати. Вы не должны явно вызывать деструктор, поэтому Renee.~MovieMonster(); это плохой код.

2. Ошибки говорят, что MovieMonster::~MovieMonster() это не определено. Можете ли вы указать, где, по вашему мнению, это определено? Потому что я с вашими инструментами для сборки….

3. кроме того, пожалуйста, используйте правильное форматирование кода, иначе будет очень сложно расшифровать структуру файла

4. Обратите внимание, что явный вызов деструктора в большинстве случаев не только плохая идея, но и обычно приводит к неопределенному поведению (поскольку он будет вызван во второй раз автоматически, когда переменная Renee выходит за пределы области действия). Вы определенно хотите избежать неопределенного поведения любой ценой!

5. Почему существует куча глобальных переменных «MovieMonster.cpp»? У вас сложилось впечатление, что вам нужно объявлять переменные с теми же именами, что и аргументы функции?

Ответ №1:

В определении класса (в MonsterMainClass_h ) говорится, что у класса MovieMonster есть конструктор, который принимает 4 аргумента, конструктор, который не принимает аргументов, и деструктор. Ни у одного из них нет определения в коде, опубликованном в вопросе.

В коде main используется конструктор с четырьмя аргументами и деструктор. В сообщениях об ошибках указывается, что ни одно из них нигде не определено.

Итак, в качестве первого прохода добавьте эти определения в MovieMonster.cpp .

И, как отмечается в одном из комментариев, не звоните Renee.~MovieMonster(); . Компилятор сделает это в конце main . В этом смысл наличия деструктора: вам не нужно беспокоиться об утилизации ресурсов, потому что деструктор будет вызван неявно.

И, пожалуйста, не #include "MovieMonster.cpp" входи CreateMonsters.cpp . У вас есть два исходных файла, которые следует хранить отдельно. В вашем проекте должны быть указаны имена обоих файлов, чтобы их можно было скомпилировать отдельно и связать.

И примечание на будущее: поскольку все четыре аргумента конструктора с четырьмя аргументами имеют значения по умолчанию, он может быть вызван без аргументов. Как и конструктор по умолчанию. Компилятор будет жаловаться на код, который не использует аргументы ( MovieMonster monster; ), потому что там могут использоваться оба конструктора.