Reputation: 217
LAST EDIT: FINAL CODE LIES AT TH END OF THE MESSAGE
i am coming from Java and I am looping for a while :
I try to implement navigability from classes Zoo to Animal and Animal to Zoo.
Q.1) did I write it the right way ? (source code on bottom)
I have got an compile error related to "stl_vector.h" class Zoo : animals.push_back(a); with message : "error:cannot increment a pointeur to incomplete type Animal"
Q.2 ) is it related to the way I implemented navigability ?
In the main.cpp, i will add animals to the zoo :
Zoo z();
std::string nom("sheeta");
Animal a(z,nom);
Q.3) the Animal constructor exists ... : why does the compiler tell me that
compile error : "no matching function for call Animal::Animal(Zoo (&)(), std::string &)
Q.4) what is the c++ way to write :
z.addAnimal(Animal(z,nom));
EDIT1 : here is what i want to implement : a zoo contains n animals, an animal knows which zoo it belongs to
LAST EDIT : picture updated with your help ==========================================
many thanks for helping !
Here are the changes i made from your precious comments :
LAST EDIT IN SOURCE CODE - 2015-12-18 07:20 gmt ===============================================
file Zoo.h
#ifndef ZOO_H
#define ZOO_H
#include <vector>
** ADDED : include Animal.h **
#include "Animal.h"
class Zoo
{
private:
std::string zooName; // no importance : name of the zoo
std::vector<Animal> animals; // list of animals
public:
Zoo(std::string n); // no importance : name of the zoo
** ADDED : const & **
void addAnimal(Animal const & a);
std::vector<Animal> getAnimals();
};
#endif
and Zoo.cpp :
#include "Zoo.h"
** REMOVED : include Animal.h
//#include "Animal.h"
Zoo::Zoo(std::string n) // no importance, n is the name of the zoo
{
zooName = n;
** REMOVED : **
//std::vector<Animal> animals(); // <<< REMOVED
}
** ADDED : const & **
void Zoo::addAnimal(Animal const &a) // <<<< const added
{
animals.push_back(a); // add an animal to the zoo
}
std::vector<Animal> Zoo:: getAnimals()
{
return animals;
}
And Animal.h
#ifndef ANIMAL_H
#define ANIMAL_H
#include <string>
** ADDED : forward declaration of Zoo **
class Zoo;
** REMOVED : include file
// #include "Zoo.h"
class Animal
{
private:
** CHANGED : pointer to Zoo **
Zoo * zoo; // in which zoo <<< CHANGED TO A POINTER
std::string nom; // name of an animal
public:
** CHANGED : pointer to Zoo AND REMOVE & after string**
// Animal(Zoo z, std::string & n);
Animal(Zoo * z, std::string n);
std::string toString();
};
#endif
And Animal.cpp :
#include "Animal.h"
** ADDED : include "Zoo.h"**
#include "Zoo.h"
#include <sstream> // ADDED TO CONVERT number to string
** CHANGED : pointer to Zoo AND REMOVED & after string**
//Animal::Animal(Zoo z, std::string & n) //
Animal::Animal(Zoo * z, std::string n) //
{ zoo = z; nom= n;
}
std::string Animal::toString()
{
** CHANGED : to justify the use of Zoo inside Animal **
std::string msg1 (" among ");
std::string msg3 (" other animals") ;
// to convert number to string
std::ostringstream chaine;
chaine << zoo->getAnimals().size();
std::string msg2(chaine.str());
return (name+msg1+msg2+msg3);
}
EDIT3 - And a main function to test these classes :
#include <iostream>
#include "Animal.h"
#include "Zoo.h"
int main()
{
std::string zooName("BigZoo");
Zoo z(zooName);
std::string nom;
std::cin >> nom;
while (nom.compare("*") != 0)
{
**CHANGED : 2 lines deleted and 1 line added
// Animal a(&z,nom);
// z.addAnimal(a);
z.addAnimal(Animal(&z, nom));
std::cin >> nom;
}
for (unsigned int i=0;i<z.getAnimals().size(); i++)
{ // for each animal of the zoo
std::cout << z.getAnimals().at(i).toString() << std::endl;
}
return 0;
}
And a test to end :
>max
>bill
>jumbo
>sheeta
>*
max among 4 other animals
bill among 4 other animals
jumbo among 4 other animals
sheeta among 4 other animals
well done, stackoverflow is really great !!! thanks again
=====================================
FINAL HEADER CODE
=====================================
/* Zoo.h */
#ifndef ZOO_H
#define ZOO_H
#include <vector>
#include <string>
#include "Animal.h"
class Zoo
{
private:
std::string zooName;
std::vector<Animal> animals; // liste of animals
public:
Zoo(std::string n);
void addAnimal(Animal const & a);
std::vector<Animal> getAnimals();
};
#endif
/* Animal.h */
#ifndef ANIMAL_H
#define ANIMAL_H
#include <string>
class Zoo;
class Animal
{
private:
Zoo *zoo ; // in which zoo
std::string name; // name of an animal
public:
Animal(Zoo *z, std::string n);
std::string toString();
};
#endif
Upvotes: 0
Views: 1355
Reputation: 125
Made some corrections and compiled the code, Animal.h,
#ifndef ANIMAL_H
#define ANIMAL_H
#include <string>
class Zoo;
class Animal
{
private:
Zoo& zoo; // in which zoo
std::string nom; // name of an animal
public:
Animal(Zoo &z, std::string & n);
std::string toString();
};
#endif
Zoo.h,
#ifndef ZOO_H
#define ZOO_H
#include <vector>
#include "Animal.h"
class Animal;
class Zoo
{
private:
std::vector<Animal> animals; // list of animals
public:
Zoo();
void addAnimal(Animal & a);
std::vector<Animal> getAnimals();
};
#endif
Animal.cpp,
#include "Animal.h"
Animal::Animal(Zoo & z, std::string & n) : zoo(z), nom(n)
{ /* zoo = z; nom= n;*/
}
std::string Animal::toString()
{
return nom;
}
Zoo.cpp,
#include "Zoo.h"
Zoo::Zoo()
{
std::vector<Animal> animals(); // list of animals
}
void Zoo::addAnimal(Animal &a)
{
animals.push_back(a); // add an animal to the zoo
}
std::vector<Animal> Zoo:: getAnimals()
{
return animals;
}
Main.cpp
Zoo z;
std::string nom("sheeta");
Animal a(z,nom);
Changes are, 1) Zoo zoo; to Zoo& zoo; -> I think here you need to store the reference of the zoo than creating a new object, correct?
2) Correct the header inclusions to resolve the compilation errors as in the code below.
Upvotes: 0
Reputation: 92341
Q1. When declaring a vector<Animal>
the Animal
class has to be a complete class. Unlike Java, C++ stores the member elements by value and not by reference.
Q2 & Q3. Zoo z();
declares a function taking no parameters and returning a Zoo
. So you try to use a function name in the constructor of Animal
. Doesn't work.
Q4. Creating a temporary parameter works, provided the addAnimal
takes a const reference to the parameter - void addAnimal(Animal const& a);
.
And, easy on the getters! Returning a copy (cloning?) of all the animals from the Zoo seems a bit much. What is the use of getAnimals
, other than creating a new zoo?
Also, real animals at a zoo generally don't know which zoo they belong to. So having a reference in the Animal
object seems a bit odd.
Also (2), std::vector<Animal> animals();
is another function declaration, just like Zoo z();
. You have to watch out for those.
Upvotes: 1
Reputation: 16771
vector<Animal>
requires Animal
to be a complete type at this point, so you need to change Zoo.h to #include "Animal.h"
. In Animal.h you can forward declare class Zoo;
But you also need to change the Animal member zoo to a reference Zoo &zoo;
.
Upvotes: 1