Я изучаю конструкторы в C ++, но компилятор MSVS ведет себя странно, и я не понимаю, почему. Успех компилятора, похоже, зависит от недавних попыток компиляции. Я ожидаю, что если мой код успешно компилируется один раз, он всегда должен успешно компилироваться, а если он дает ошибку, он всегда должен давать ошибку. С моим кодом здесь это не так. Я использую отладчик в бесплатной среде MSVS 2019 на Windows 10.
У меня есть 3 файла, которые формируют мой проект, и 3 разные версии проекта, которые я назову A, B и C.
Версия A - это код, представленный на первых трех экранах ниже. Я думаю, что версия А должна скомпилироваться и работать так, как я ожидаю. Любые фактические ошибки в версии A, вероятно, являются вторичными по отношению к этому вопросу. Код должен определить класс, создать экземпляр класса (запустить конструктор), вызвать метод класса и, наконец, вызвать деструктор. для этого объекта, когда программа завершается.
Следующий код находится в Cat.h.
#pragma once
#include <iostream>
class Cat {
private:
bool happy;
public:
Cat();
~Cat();
void meow();
};
Следующее находится в файле Cat.cpp.
#include <iostream>
#include "Cat.h"
Cat::Cat() {
std::cout << "Creating Cat" << std::endl;
happy = false;
};
Cat::~Cat() {
std::cout << "Deleting Cat..." << std::endl;
};
void Cat::meow() {
if (happy) {
std::cout << "Meow" << std::endl;
}
else
{
std::cout << "SSSSSsssss" << std::endl;
}
return;
};
Вот мой основной файл.
#include "Cat.h"
int main() {
Cat cat;
cat.meow();
}
Версия B идентична версии A , за исключением одного изменения, которое объявляется в конструкторе для Cat, что делает счастливой локальную переменную конструктора.
Cat::Cat() {
std::cout << "Creating Cat" << std::endl;
bool happy = false;
}
Версия C идентична версии A , за исключением явной ошибки, заключающейся в том, что точка с запятой удаляется после объявления класса в Cat.h.
Cat();
~Cat();
void meow();
}
Теперь о странном поведении.
Если я впервые попытаюсь скомпилировать версию A , я получу следующие ошибки:
1>Debug\Cat.obj : warning LNK4042: object specified more than once; extras ignored
1>Source.obj : error LNK2019: unresolved external symbol "public: __thiscall Cat::Cat(void)" (??0Cat@@QAE@XZ) referenced in function _main
1>Source.obj : error LNK2019: unresolved external symbol "public: __thiscall Cat::~Cat(void)" (??1Cat@@QAE@XZ) referenced in function _main
1>Source.obj : error LNK2019: unresolved external symbol "public: void __thiscall Cat::meow(void)" (?meow@Cat@@QAEXXZ) referenced in function _main
Если я сейчас изменю версию A на версию B и скомпилирую, я не получу ошибок, но я не инициализируюсь счастливым в конструкторе cat. Если я затем изменю версию B на версию A , код компилируется и запускается так, как я ожидал.
Теперь версия A компилируется и запускается, даже несмотря на то, что это тот же код, который выдавал мне ошибку раньше.
Если я сейчас изменю версию A на версию C и скомпилирую, я получу очевидную ошибку:
1>Cat.cpp
error C2533: 'Cat::{ctor}': constructors not allowed a return type
1>Cat.h
fatal error C1004: unexpected end-of-file found
Если я теперь изменю версию C на версию A и скомпилирую, я получу ту же ошибку, которая произошла после первоначальной компиляции версии A . Возвращение к версии B и обратно исправляет эту проблему.