C ++:class A引用classe B(在向量中)和B类引用A(只有一个)

时间:2015-12-17 15:29:11

标签: c++ class

最后编辑:发送消息结束时的最终代码

我来自Java,我正在循环一段时间:

我尝试实现从类Zoo到Animal and Animal到Zoo的导航功能。

Q.1)我是以正确的方式写的吗? (源代码在底部)

我遇到了与“stl_vector.h”相关的编译错误 class Zoo:animals.push_back(a); 带有消息:“错误:无法将pointeur增加到不完整类型Animal”

Q.2)是否与我实施导航的方式有关?

在main.cpp中,我将动物添加到动物园:

Zoo z();
std::string nom("sheeta");
Animal a(z,nom);

Q.3)Animal构造函数存在......:为什么编译器会告诉我

编译错误:“没有匹配的函数用于调用Animal :: Animal(Zoo(&)(),std :: string&)

Q.4)c ++的写法是什么:

z.addAnimal(Animal(z,nom));

EDIT1:这是我想要实现的:动物园包含n只动物,动物知道它属于哪个动物园

最后编辑:图片已在您的帮助下更新 ========================================== < / p>

enter image description here

非常感谢你的帮助!

以下是您对宝贵评论所做的更改:

源代码中的最后编辑 - 2015-12-18 07:20 gmt ===============================================

文件Zoo.h

#ifndef ZOO_H
#define ZOO_H

#include <vector>

**增加:包括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

**增加:const&amp; **

    void addAnimal(Animal const & a); 
    std::vector<Animal>  getAnimals();
};

#endif

和Zoo.cpp:

#include "Zoo.h"

**删除:包括Animal.h

//#include "Animal.h"

Zoo::Zoo(std::string  n) // no importance, n is the name of the zoo
    {
        zooName = n;

**删除:**

        //std::vector<Animal> animals(); // <<< REMOVED
    }

**增加:const&amp; **

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;
    }

和Animal.h

#ifndef ANIMAL_H
#define ANIMAL_H
#include <string>

** ADDED:Zoo **的前向声明

class Zoo;

**删除:包含文件

// #include "Zoo.h"    

class Animal
{
  private:

**已更改:指向Zoo **的指针

    Zoo * zoo; // in which zoo   <<< CHANGED TO A POINTER
    std::string nom;  // name of an animal

  public:

**已更改:指向Zoo AND REMOVE&amp;的指针在字符串**

之后
    // Animal(Zoo z, std::string & n); 
    Animal(Zoo * z, std::string n); 
    std::string toString();
};

#endif

和Animal.cpp:

#include "Animal.h"

**增加:包括“Zoo.h”**

#include "Zoo.h"
#include <sstream> // ADDED TO CONVERT number to string

**已更改:指向Zoo AND REMOVED&amp;的指针在字符串**

之后
//Animal::Animal(Zoo  z, std::string & n) // 
 Animal::Animal(Zoo * z, std::string  n) // 
    {  zoo = z; nom= n;
    }

std::string Animal::toString()
    {

**已更改:证明在Animal **中使用Zoo

    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 - 以及测试这些类的主要功能:

 #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)
    {

**已更改:删除了2行并添加了1行

    //    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;
}

结束测试:

>max 
>bill
>jumbo
>sheeta
>*
 max among 4 other animals
 bill among 4 other animals
 jumbo among 4 other animals
 sheeta among 4 other animals

做得好,stackoverflow非常棒!!!再次感谢

=====================================

最终标题代码

=====================================

/* 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

3 个答案:

答案 0 :(得分:1)

此时

vector<Animal>要求Animal为完整类型,因此您需要将Zoo.h更改为#include "Animal.h"。在Animal.h中,您可以转发声明class Zoo;但您还需要将动物成员动物园更改为引用Zoo &zoo;

答案 1 :(得分:1)

Q1。声明vector<Animal>时,Animal类必须是完整的类。与Java不同,C ++按值存储成员元素,而不是按引用存储。

Q2&amp; Q3。 Zoo z();声明一个不带参数的函数并返回Zoo。因此,您尝试在Animal的构造函数中使用函数名称。不起作用。

Q4。如果addAnimal对参数void addAnimal(Animal const& a);采用const引用,则创建临时参数有效。

而且,吸气剂容易!从动物园返回所有动物的副本(克隆?)似乎有点多。除了创建一个新动物园之外,getAnimals有什么用?

此外,动物园里的真实动物通常不知道它们属于哪个动物园。所以在Animal对象中有一个引用似乎有点奇怪。

同样(2),std::vector<Animal> animals();是另一个函数声明,就像Zoo z();一样。你必须注意那些。

答案 2 :(得分:-1)

进行了一些更正并编译了代码, Animal.h,

BaseModel

Zoo.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

Animal.cpp,

#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

Zoo.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;
    }

Main.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;
    }

变化是, 1)动物园动物园;去动物园&amp;动物园; - &GT;我想在这里你需要存储动物园的引用而不是创建一个新对象,对吗?

2)更正标题包含以解决编译错误,如下面的代码所示。