0

Ok, so I've tried to get more familiar with OOP in C++ and I got the following code:

//main.cpp
#include <iostream>
#include "ZooAnimal.h"

using namespace std;

int main()
{
    ZooAnimal bozo;
    bozo.set_name(12);
    // bozo.Create("Bozo", 408, 1027, 400);

    // cout << "This animal's name is " << bozo.reptName() << endl;

    // bozo.Destroy();
    cout << "Hello";
}
//ZooAnimal.h
#ifndef ZOOANIMAL_H
#define ZOOANIMAL_H

class ZooAnimal
{
private:
    std::string name;
    int cageNumber;
    int weightDate;
    int weight;

public:
    void Create(std::string, int, int, int);
    void Destroy();
    std::string reptName();
    int daysSinceLastWeighted(int today);
    void set_name(int);
};

#endif //ZooAnimal

and lastly,

//ZooAnimal.cpp
#include "ZooAnimal.h"
#include <iostream>

void ZooAnimal::Create(std::string a, int b, int c, int d)
{
    //This creates a ZooAnimal Object
    name = a;
    cageNumber = b;
    weightDate = c;
    weight = d;
}

int ZooAnimal::daysSinceLastWeighted(int today)
{
    //calculate how many days have passed since last weight
    return today - weightDate;
}

//clear up the memory
void ZooAnimal::Destroy()
{
    delete &name;
}

// return the animal name
std::string ZooAnimal::reptName()
{
    return name;
}

void ZooAnimal::set_name(int a)
{
    cageNumber = a;
}

So, when I try to run this code(from main.cpp of course) it won't compile and I get the following message in the console

C:\Users\<user>\AppData\Local\Temp\ccOiWb7r.o:main.cpp:(.text+0x2e): undefined reference to `ZooAnimal::set_name(int)'
collect2.exe: error: ld returned 1 exit status

I'm using MinGW to compile, working on a Windows 10 machine. The weird thing is that when I try to run the same code on a cloud editor, like repl.it , it works just fine, and if I don't separate my code into multiple files, again, it runs fine. Any idea of what can I do?

AMC
  • 2,642
  • 7
  • 13
  • 35
Corolo
  • 3
  • 1
  • Is that the entire error message? – AMC Feb 15 '20 at 00:21
  • Side-note: Why do you have a `Create` method (that requires the instance to be created with no initialized fields, then `Create`ed), rather than using an actual constructor? – ShadowRanger Feb 15 '20 at 02:09
  • Okay, thank you guys for helping. The problem was I was using VS code for writing and an extension named "Code-runner" to compile the project, but it only built the main.cpp file so that was it. I've got an extension named Easy C++ project after doing some more digging and it seems to work fine but I think I might have to switch to CLion soon. Thank you guys very much <3 – Corolo Feb 16 '20 at 11:21

2 Answers2

1

You are building main.cpp but not ZooAnimal.cpp. Try putting some obvious syntax error into ZooAnimal.cpp--does the compiler complain? If not, you aren't compiling ZooAnimal.cpp at all. If the compiler does complain about the syntax error, then you are compiling ZooAnimal.cpp but not passing ZooAnimal.o to the linker, resulting in the undefined symbol set_name().

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
0

if I don't separate my code into multiple files, again, it runs fine. Any idea of what can I do?

Therein lies the clue to your problem. The linker can find the void ZooAnimal::set_name(int a) function in the one file. But when you separate your code into separate files you must tell the linker where it can find the definition of the function.

You can do this as follows. I'm using gcc

g++ -c file1.cpp  //compile your first source file
g++ -c file2.cpp  //and now the second
g++ -o myprog.exe file1.o file2.o //link the 2 object files to get your .exe

As a next step you can also compile and build by using a makefile where you specify where the linker can find all the object code for the various functions you've written. Remember you may have multiple files down the road. For this exercise it might be overkill but you can read about it here.

pcodex
  • 1,812
  • 15
  • 16