C ++:试图通过引用向量来理解传递

时间:2013-12-13 21:56:40

标签: c++ vector pass-by-reference

我正在学习C ++,我真的不明白如何通过函数传递对象。我读到有三种方法可以做到这一点。通过值,引用和指针传递。我想我想通过参考做什么?

我很确定我在通过引用传递时遇到问题,因为我尝试在主要测试它而不通过执行调用函数

std::string nameInput = "Penguin";
std::string colorInput = "Black";
Animal temp(nameInput,colorInput);
zoo.addAnimal(temp);
zoo.printDatabase();

它运作得很好。但是当我尝试通过函数调用它时,我甚至无法将其添加到vector.Before发布之前我尝试了addAnimal(Animal& toAdd),但我不确定究竟发生了什么。因为我不是只是将地址传递给函数?而不是对象动物本身。

或许我完全看错了方向。这就是为什么我喜欢在这里发帖,因为拥有另一双眼睛总是很好!

//Zoo.h

#include<vector>
#include<animal.h>

#ifndef ZOO_H_
#define ZOO_H_

class Zoo{
    private:
        std::vector<Animal> database;
    public:
        void addAnimal(animal toAdd);
        void printDatabase();
};

#endif ZOO_H_

//Animal.h

#include<string>

#ifndef ANIMAL_H_
#define ANIMAL_H_

class Animal{
    private:
        std::string name;
        std::string color;

    public:
        Animal(std::string name, std::string color);
        void printInfo();
}

#endif ANIMAL_H_


//Zoo methods
void Zoo::printDatabase(){
    for(std::vector<Animal>::iterator list = database.begin(); list != list.end(); list++){
        (*list).printInfo();
    }
}

void Zoo::addAnimal(Animal toAdd){
    database.push_back(toAdd);
}

//Animal Methods
Animal::Animal(std::string inputName, std::string inputColor){
    name = inputName;
    color = inputColor;
}

void Animal::printInfo(){
    std::cout << "Name: " << name << "\n";
    std::cout << "Color: " << color >> "\n";
}


//main.cpp
int main(){

    Zoo zoo;
    std::string input;
    do{
        printMenu();
        std::getline(std::cin, input);
        if(!input.empty()){
            decide(input, zoo);
        }
    }while(input != "3";
}

void printMenu(){
    std::cout <<"Zoo database\n";
    std::cout << "1.Add  Animal \n";
    std::cout << "2.Print \n";
    std::cout << "3.Exit \n";
}

void decide(std::string input, Zoo zooInput){

    std::string name;
    std::string color;

    if(input == "1"){
        std::cout << "Please enter the name of the animal to add \n";
        std::getline(std::cin,name);
        std::cout << "Please enter the color of the animal \n";
        std::getline(std::cin,color);

        Animal temp(name,color);
        zooInput.addAnimal(temp);
    }

    if(input == "2"){
        zooInput.printDatabase();
    }
}

3 个答案:

答案 0 :(得分:1)

不确定我是否理解你所要求的但是在你的决定函数中,你不是通过引用或指针传递,而是通过值传递。

您希望通过引用传递动物园,因为您希望该函数修改传递给它的动物园,而不是复制它并修改它。

另外,addAnimal很好,因为你确实希望在这里传递值。不是通过引用或指针,因为调用函数中的动物将在以后被销毁。

答案 1 :(得分:1)

正如评论中所述,您希望将函数的签名更改为:

void decide(std::string input, Zoo& zooInput){

在这些行中:

Animal temp(name,color);
zooInput.addAnimal(temp);

temp的副本传递给addAnimal,然后复制/移动到zooInput的向量中。通过引用传递它将没有任何区别,因为它无论如何都会被复制到矢量中。

但是,因为zooInput是按值传递的,所以对它的更改不会反映在函数外部。

答案 2 :(得分:1)

首先,这甚至不应该编译......

  1. 您忘了将;放在Animal课程声明的末尾。
  2. main()函数中,while循环中没有结束),此处为:while(input != "3";
  3. 然后,void addAnimal(animal toAdd);animal等方法未在任何地方声明,应该是Animal
  4. 在for循环中,您有for(std::vector<Animal>::iterator list = database.begin(); list != list.end(); list++){。显然,list是一个迭代器,它没有end()方法,因此list != list.end()是完全错误的。
  5. std::cout << "Color: " << color >> "\n";中,您使用>> "\n",这是错误的。
  6. 使用std::getline(std::cin, input);然后使用if(!input.empty())不起作用。它可能会卡在EOF上的不定式循环中。
  7. 最后,回到参考文献。您将Zoo按值(副本)传递到decide()函数中。因此,它将动物添加到自己的Zoo私有副本中,该副本在离开函数范围时被销毁。因此,Zoo中定义的main()对象永远不会被修改。要解决此问题,请将void decide(std::string input, Zoo zooInput)更改为void decide(std::string input, Zoo& zooInput)

    这是你的程序,有些修复:

    #include <string>
    #include <vector>
    #include <iostream>
    
    class Animal {
        std::string name;
        std::string color;
    
    public:
        Animal(std::string name, std::string color);
        void printInfo();
    };
    
    class Zoo {
        std::vector<Animal> database;
    public:
        void addAnimal(Animal toAdd);
        void printDatabase();
    };
    
    void Zoo::printDatabase(){
        for(std::vector<Animal>::iterator list = database.begin(); list != database.end(); list++){
            (*list).printInfo();
        }
    }
    
    void Zoo::addAnimal(Animal toAdd){
        database.push_back(toAdd);
    }
    
    Animal::Animal(std::string inputName, std::string inputColor){
        name = inputName;
        color = inputColor;
    }
    
    void Animal::printInfo(){
        std::cout << "Name: " << name << "\n";
        std::cout << "Color: " << color << "\n";
    }
    
    void printMenu(){
        std::cout <<"Zoo database\n";
        std::cout << "1.Add  Animal \n";
        std::cout << "2.Print \n";
        std::cout << "3.Exit \n";
    }
    
    void decide(std::string input, Zoo& zooInput) {
        std::string name;
        std::string color;
    
        if(input == "1"){
            std::cout << "Please enter the name of the animal to add \n";
            std::getline(std::cin,name);
            std::cout << "Please enter the color of the animal \n";
            std::getline(std::cin,color);
    
            Animal temp(name,color);
            zooInput.addAnimal(temp);
        }
    
        if(input == "2"){
            zooInput.printDatabase();
        }
    }
    
    int main() {
        Zoo zoo;
        std::string input;
        printMenu();
        while (std::getline(std::cin, input)) {
            decide(input, zoo);
            if (input == "3")
                break;
            printMenu();
        }
    }
    

    示例运行:

    $ g++ -Wall -pedantic -std=c++11 -o test ./test.cc  && ./test 
    Zoo database
    1.Add  Animal 
    2.Print 
    3.Exit 
    1
    Please enter the name of the animal to add 
    cow
    Please enter the color of the animal 
    blue
    Zoo database
    1.Add  Animal 
    2.Print 
    3.Exit 
    2
    Name: cow
    Color: blue
    Zoo database
    1.Add  Animal 
    2.Print 
    3.Exit 
    1
    Please enter the name of the animal to add 
    lobster
    Please enter the color of the animal 
    green
    Zoo database
    1.Add  Animal 
    2.Print 
    3.Exit 
    2
    Name: cow
    Color: blue
    Name: lobster
    Color: green
    Zoo database
    1.Add  Animal 
    2.Print 
    3.Exit 
    3
    $