1

I'm compiling it with g++ zoo.cpp Animal.cpp -o out and keep getting the following errors:

Output

The function definition and declarations match as well. I had it working before but I can't figure out what changed or what the referencing means. The "Animal.h" header file is included in both .cpp files.

zoo.cpp

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

using namespace class1020;

int main( int argc, char** argv )
{
    Animal* zoo = Zoo( 3,      2,      10,      10 );

    ShowTheZoo(zoo);

    for( int i=0;i<15;i++ )
    {
        std::cout << "\t\tYEAR " << i << std::endl;
        SpawningCycle(zoo);
        FeedingCycle(zoo);
        zoo = AgingCycle(zoo);
        ShowTheZoo(zoo);    
    }

    CleanTheZoo(zoo);

    return 0;

}

Animal.cpp

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

using namespace class1020;

Animal* Zoo(int numBirds, int numWorms, int numWolves, int numHares){}

void SpawningCycle(Animal* linkedlist){}

void FeedingCycle(Animal* linkedlist){}

Animal* AgingCycle(Animal* linkedlist){}

void ShowTheZoo(Animal* linkedlist){}

void CleanTheZoo(Animal* linkedlist){}

Animal.h

#ifndef ANIMAL_H
#define ANIMAL_H


#include <string>


namespace class1020
{

class Animal
{
  public:

    Animal(int lifespan, std::string anim_type);
    virtual ~Animal();

    virtual Animal* produceOffspring() = 0;

  private:


    Animal();

};

Animal* Zoo(int numBirds, int numWorms, int numWolves, int numHares);

void SpawningCycle(Animal* linkedlist);

void FeedingCycle(Animal* linkedlist);

Animal* AgingCycle(Animal* linkedlist);

void ShowTheZoo(Animal* linkedlist);

void CleanTheZoo(Animal* linkedlist);

};

#endif
Codite
  • 37
  • 5
  • See [this question](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – 1201ProgramAlarm Feb 29 '20 at 21:38

1 Answers1

2

You are not actually defining the functions and Animal member functions in the namespace class1020 when you do using namespace class1020;. That only makes definitions in class1020 available without fully using their fully qualified names.

This would however define the functions in that namespace:

namespace class1020 {

Animal* Zoo(int nb_tigers, int nb_hyenas, int nb_possums, int nb_chickens){}

void SpawningCycle(Animal* linkedlist){}

void FeedingCycle(Animal* linkedlist){}

Animal* AgingCycle(Animal* linkedlist){}

void ShowTheZoo(Animal* linkedlist){}

void CleanTheZoo(Animal* linkedlist){}

}

You have also forgotten to define the constructors and destructor for Animal

They also need to be defined in the same namespace:

namespace class1020 {
    Animal::Animal() { /* something */ }

    Animal::Animal(int lifespan, std::string anim_type) {
        /* something */
    }

    Animal::~Animal() { /*something*/ }
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • When I try to create a class object using Animal* animal(10, "bird"); I get the error excess elements in scalar initializer. Does this not point to the Animal constructor for lifespan and animal type? – Codite Feb 29 '20 at 21:08
  • 1
    `Animal* animal(10, "bird");` looks like a `Animal*` initialized with `(10,"bird")`. That won't fly (pardon the pun). A pointer variable needs a pointer value. so if it's a pointer you need `Animal* animal = new Animal(10, "bird");` - but try to stay away from raw pointers. You rarely need them. Try to stay with automatic variables instead: `Animal animal(10,"bird");` – Ted Lyngmo Feb 29 '20 at 21:12
  • Pardon the storm of errors. When I tried that earlier I received "error: variable type 'class1020::Animal' is an abstract class -- Animal animal(10, "bird");" – Codite Feb 29 '20 at 21:27
  • @Codite No worries! Did you implement all member functions for `Animal`? (notice I just removed an erroneous `virtual` in the implementation - my bad). Do you have any `Animal` functions that you haven't shown here? Are they made pure virtual (`= 0`)? – Ted Lyngmo Feb 29 '20 at 21:29
  • Yes, I do. virtual Animal* produceOffspring() = 0; which has to be declared and implemented in a derived class – Codite Feb 29 '20 at 21:43
  • @Codite There you have it. That makes `Animal` abstract. You can never instantiate `Animal` - but you can hold pointers or references to `Animal` derivates and call the derived classes' functions through them. So, my note about staying with automatic variables becomes sort of void. I didn't know it was abstract. `Animal* a = new Tiger;` would work if `Tiger` is derived from `Animal` for example - and implements the pure virtual functions that is ... – Ted Lyngmo Feb 29 '20 at 21:45
  • One concern: You've shown a lot of free functions acting on `Animal*` but no inheritance. In this scenario, there must be inheritance. – Ted Lyngmo Feb 29 '20 at 21:52
  • I edited the original code to reflect the problem I'm currently having. This whole time my goal has been to create a derived object of a bird while setting its lifespan and animal type. Animal* bird = new bird; – Codite Feb 29 '20 at 23:03
  • @Codite Editing your original question, that has been answered, so the problem is something else will make people who search for help for something similar confused. They'll only see your new question with an accepted answer that does not work at all. It's better to ask separate questions. This one is done I'd say, but if you don't retract your latest edits, it'll stay confusing. Just take it from where you've come now and ask anew - and back the edits to where it was when you accepted my answer - or my answer is rubbish and I'll need to remove it. :-) – Ted Lyngmo Feb 29 '20 at 23:12