1

For my class assignment, we had to make a C++ program using a class and then compile it. These are the following.

Snake.h

#ifndef SNAKE_H
#define SNAKE_H

#include <iostream>
using namespace std;

// We need to include string since we need to access it
#include <string>
using std::string;
// Our declaration of our class
class Snake
{
public:
    // These are our properties
    string color;
    double length;
    bool venomous;

    // Our two constructors, this is basically saying the snake is able to create these datatypes.
    // It can either have a default data used or inputted data when called.
    Snake()
    {
    }
    // This one has the parameters
    Snake(string color, double length, bool venomous)
    {
    }

    // Our functions that we are declaring so we can use them in snake.cpp
    // These aren't declared here because we don't have any data yet that they can use
    // We also are just telling the code that they are here and that they may or
    // may not be called at some point

    void display();
    void bite();
};

#endif

Snake.cpp

#include <iostream>
#include "Snake.h"

// These creates our data from the header file.
// Snake is seen below with the default data and then Snake with the parameters can be seen.
Snake::Snake()
{
    color = "Red";
    length = 12.5;
    venomous = false;
}

Snake::Snake(string newColor, double newLength, bool newVenomous)
{
    color = newColor;
    length = newLength;
    venomous = newVenomous;
}

// These initalize these functions so that they can be used when we do our dot callback in our main.
void Snake::bite()
{
    cout << "This snake bites because he is hungry";
}

void Snake::display()
{
    cout << "The color of the snake is: " << color;
    cout << "The length of the snake is: " << length;
    cout << "Is the snake venomous: " << venomous;
}

main.cpp

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

int main()
{
    // We create our first snake
    Snake snake1;
    // Now we need to call method that our object contains
    snake1.display();
    snake1.bite();

    // UI is user input
    bool UIVenomous;
    string UIColor, isVenomous;
    double UILength;

    cout << "What color is the snake?" << endl;
    cin >> UIColor;
    cout << "How long is the snake? " << endl;
    cin >> UILength;
    cout << "Is the snake venomous? (y/n) " << endl;
    cin >> isVenomous;
    if (isVenomous == "y")
    {
        UIVenomous = true;
    }
    else if (isVenomous == "n")
    {
        UIVenomous = false;
    }

    // We now call our class and set our object with the variables from above
    Snake snake2(UIColor, UILength, UIVenomous);
    // We need to now call our methods that our object has
    snake2.display();
    snake2.bite();
}

I am using VSCode and when I try to run build task it gives me this error

C:\Users\viens\AppData\Local\Temp\cclzLMka.o: In function `main':
c:/Users/viens/OneDrive/Documents/SchoolWork/Lab3/main.cpp:10: undefined reference to `Snake::display()'
c:/Users/viens/OneDrive/Documents/SchoolWork/Lab3/main.cpp:11: undefined reference to `Snake::bite()'
c:/Users/viens/OneDrive/Documents/SchoolWork/Lab3/main.cpp:36: undefined reference to `Snake::display()'
c:/Users/viens/OneDrive/Documents/SchoolWork/Lab3/main.cpp:37: undefined reference to `Snake::bite()'
collect2.exe: error: ld returned 1 exit status
The terminal process terminated with exit code: 1
drescherjm
  • 10,365
  • 5
  • 44
  • 64
  • What compiler are you using with VS code? Most likely you are just compiling main.cpp and not Snake.cpp, hence it can't find the definition for this functions – castro Jun 03 '20 at 17:05
  • I'm using MinGW g++ to build the active file and running it through the VScode terminal. When trying to build Snake.cpp it says error: redefinition of 'Snake::Snake()' but all the examples my professor provided has done it this way – Austin Viens-DeRuissseau Jun 03 '20 at 17:09
  • they're all in the same folder so my include is correct. – Austin Viens-DeRuissseau Jun 03 '20 at 17:12
  • i figured it out, it was because in snake.h i had the functions open but they needed to be closed because i declared it somewhere else – Austin Viens-DeRuissseau Jun 03 '20 at 17:13
  • 2
    You need to compile all files and not just `main.cpp`. If you compile only `main.cpp` then `#include "Snake.h"` will still work (`main.cpp` will "see" the signatures in the `Snake` class) and `main.cpp` compiles just fine, but when generating the executable the compiler needs to link everything together and at that stage it does not find the implementations of the methods in the `Snake` class. Thus you get undefined reference erros **during the linking**. – darcamo Jun 03 '20 at 17:15
  • 1
    Your bug is most likely in your `tasks.json` file – drescherjm Jun 03 '20 at 17:19
  • 2
    Visual Studio Code is a tricky beast to wrangle. I do not recommend it to people trying to learn C++ because they wind up having to learn two things and can't effectively learn the important one, C++, until after they've learned care and feeding of Visual Studio Code. This may change in a few years , but for now you're probably better off with a pre-configured IDE like Visual Studio. – user4581301 Jun 03 '20 at 17:25
  • My tasks.json is this ```{ "version": "2.0.0", "tasks": [ { "type": "shell", "label": "g++.exe build active file", "command": "C:\\MinGW\\mingw32\\bin\\g++.exe", "args": [ "-g", "${file}", "-o", "${fileDirname}\\${fileBasenameNoExtension}.exe" ], "options": { "cwd": "C:\\MinGW\\mingw32\\bin" }, "problemMatcher": [ "$gcc" ], "group": { "kind": "build", "isDefault": true } } ] } ``` – Austin Viens-DeRuissseau Jun 03 '20 at 17:27
  • `"${file}",` is the part having the bug. That means compile only the active file and not all the cpp files you have in your workspace folder. – drescherjm Jun 03 '20 at 17:36
  • @drescherjm I took that out and tried compiling and still had an issue with my exe saying it cant be ran and isnt compatible with the version of windows im running – Austin Viens-DeRuissseau Jun 03 '20 at 17:42
  • You don't want to take that out. Taking it out means compile no files, g++ won't be happy with no files to compile. You want to replace it with the names all the .cpp files in separate arguments or use a wildcard that evaluates to all cpp files in your workspace. – drescherjm Jun 03 '20 at 17:43
  • 1
    Related: [https://stackoverflow.com/questions/47665886/vs-code-will-not-build-c-programs-with-multiple-ccp-source-files](https://stackoverflow.com/questions/47665886/vs-code-will-not-build-c-programs-with-multiple-ccp-source-files) – drescherjm Jun 03 '20 at 17:48
  • everything is in the same folder and I changed it to this ``` "args": [ "-g", "${Snake.cpp}", "${main.cpp}", "-o", "${fileDirname}\\${fileBasenameNoExtension}.exe" ],``` but it still isn't working properly. – Austin Viens-DeRuissseau Jun 03 '20 at 17:50
  • @drescherjm that worked, thanks! – Austin Viens-DeRuissseau Jun 03 '20 at 17:51
  • I don't think you wanted the `${` and `}` part around the file name. A variable in this syntax is prefixed with `${` and ended with `}` so a file names in the default folder would just be "Snake.cpp", "main.cpp", however what may trip you up is what exactly is the default folder. You may need to use a relative path if your source files are not in this folder. – drescherjm Jun 03 '20 at 17:54

2 Answers2

0

If there's an undefined reference error, usually it's because the .o file (which gets created from the .cpp file) doesn't exist and your compiler/build system is not able to link it.

You can use this in CLI: g++ main.cpp other.cpp etc.cpp

bogdyname
  • 358
  • 2
  • 10
  • 1
    I dunno about usually. It looks to be true for this case, but a lot of the time it's a silly typo. or the prototype not matching the implementation. – user4581301 Jun 03 '20 at 17:37
0

It compiled regularly after I removed the bodies of constructors in the header file.

/* Snake.h
*/
Snake();
Snake(string color, double length, bool venomous);