简体   繁体   English

C ++:尝试理解对矢量的引用

[英]C++: Trying to understand pass by reference to vectors

I am learning C++ and I don't really understand how to pass objects through functions. 我正在学习C ++,但我不太了解如何通过函数传递对象。 I read that there were three ways to do it. 我读到有三种方法可以做到这一点。 Passing by value,reference and pointer. 通过值,引用和指针传递。 I think I am trying to do by reference? 我想我想参考一下吗?

I am pretty sure I am having issues with passing by reference because I tried to test it in the main without calling functions by doing 我很确定我在通过引用传递时遇到问题,因为我试图在不进行函数调用的情况下在主函数中对其进行测试

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

And it works out fine. 而且效果很好。 But when I try to call it through functions I am not even able to add it to the vector.Before posting this I tried addAnimal(Animal &toAdd) but I am not sure what is really going on. 但是当我尝试通过函数调用它时,我什至无法将其添加到向量中。在发布此函数之前,我尝试了addAnimal(Animal&toAdd),但我不确定到底发生了什么。 Because aren't I just passing in the address to the function? 因为我不只是将地址传递给函数吗? And not the object animal itself. 而不是对象动物本身。

Or maybe I am totally looking at the wrong direction. 也许我完全在看错方向。 Which is why I like posting here because having another set of eyes is always nice! 这就是为什么我喜欢在这里发布的原因,因为拥有另一双眼睛总是很好!

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

Not sure if I understand what you're asking but in your decide function, you aren't passing by reference or pointer, but by value. 不知道我是否理解您的要求,但是在您的Decision函数中,您不是通过引用或指针传递,而是通过值传递。

You want to pass the zoo by reference since you expect the function to modify the zoo passed to it, not make a copy of it and modify that. 您希望通过引用传递动物园,因为您希望该函数修改传递给动物园的动物园,而不是对其进行复制和修改。

Also, addAnimal is fine, because you do want to pass by value here. 另外,addAnimal很好,因为您确实想在此处按值传递。 Not by reference or pointer, because the animal in the calling function is going to get destroyed later. 不能通过引用或指针,因为调用函数中的动物将在以后被销毁。

As already stated in the comment, you want to change your function's signature to: 如评论中所述,您想将函数的签名更改为:

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

In these lines here: 在这些行中:

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

A copy of temp is passed to addAnimal and subsequently copied/moved into zooInput 's vector. temp的副本传递给addAnimal ,然后将其复制/移动到zooInput的向量中。 Passing it by reference will make no difference because it is copied into the vector anyway. 通过引用传递它不会有任何区别,因为无论如何它都会被复制到向量中。

However, because zooInput is passed by value, changes to it will not be reflected outside the function. 但是,由于zooInput是按值传递的,因此zooInput更改将不会在函数外部反映出来。

First of all, this should not even compile... 首先,这甚至不应该编译...

  1. You forgot to put ; 你忘了放; at the end of Animal class declaration. Animal类声明的末尾。
  2. In main() function, there is no closing ) in while loop, here: while(input != "3"; main()函数中,while循环中没有close ) ,在这里: while(input != "3";
  3. Then you have methods like void addAnimal(animal toAdd); 然后,您将拥有像void addAnimal(animal toAdd);这样的方法void addAnimal(animal toAdd); and animal is not declared anywhere, should have been Animal . 并且animal没有在任何地方声明,应该是Animal
  4. In your for loop, you have for(std::vector<Animal>::iterator list = database.begin(); list != list.end(); list++){ . 在您的for循环中,您有for(std::vector<Animal>::iterator list = database.begin(); list != list.end(); list++){ Obviously, list is an iterator and it does not have end() method, so list != list.end() is plain wrong. 显然, list是一个迭代器,它没有end()方法,因此list != list.end()是完全错误的。
  5. In std::cout << "Color: " << color >> "\\n"; std::cout << "Color: " << color >> "\\n"; , you use >> "\\n" , which is just wrong. ,则使用>> "\\n" ,这是错误的。
  6. Using std::getline(std::cin, input); 使用std::getline(std::cin, input); and then if(!input.empty()) does not work. 然后if(!input.empty())不起作用。 It could just get stuck in infinitive loop on EOF . 它可能会陷入EOF无限循环中。

And finally, back to references. 最后,返回参考。 You pass Zoo by value (copy) into your decide() function. 您通过值(副本)将Zoo传递到您的decide()函数中。 Therefore, it adds an animal into its own private copy of Zoo which is destroyed upon leaving the function scope. 因此,它将动物添加到其自己的Zoo私有副本中,该副本在离开功能范围时被销毁。 Therefore, Zoo object defined in main() is never modified. 因此,永远不会修改main()定义的Zoo对象。 To fix it, change void decide(std::string input, Zoo zooInput) to void decide(std::string input, Zoo& zooInput) . 要解决此问题, void decide(std::string input, Zoo zooInput) void decide(std::string input, Zoo& zooInput) void decide(std::string input, Zoo zooInput)更改为void decide(std::string input, Zoo& zooInput) void decide(std::string input, Zoo zooInput) void decide(std::string input, Zoo& zooInput)

And here is your program, somewhat fixed: 这是您的程序,有些固定:

#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();
    }
}

Example run: 示例运行:

$ 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
$ 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM