【问题标题】:C++: Trying to understand pass by reference to vectorsC++:试图理解通过引用传递向量
【发布时间】:2014-01-01 19:47:24
【问题描述】:

我正在学习 C++,但我并不真正了解如何通过函数传递对象。我读到有三种方法可以做到这一点。通过值、引用和指针传递。我想我想通过引用来做?

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

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

而且效果很好。但是当我尝试通过函数调用它时,我什至无法将它添加到向量中。在发布之前我尝试了 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();
    }
}

【问题讨论】:

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


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      在这几行中:

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

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

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

      【讨论】:

      • 老实说,我从没想过动物园是我的问题。谢谢!如果我有足够的声誉来投票,我会的!
      【解决方案3】:

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

      1. 您忘记将; 放在Animal 类声明的末尾。
      2. main()函数中,在while循环中没有关闭),这里:while(input != "3";
      3. 然后你有像void addAnimal(animal toAdd);animal这样的方法没有在任何地方声明,应该是Animal
      4. 在你的 for 循环中,你有 for(std::vector&lt;Animal&gt;::iterator list = database.begin(); list != list.end(); list++){。显然,list 是一个迭代器,它没有end() 方法,所以list != list.end() 是完全错误的。
      5. std::cout &lt;&lt; "Color: " &lt;&lt; color &gt;&gt; "\n"; 中,您使用&gt;&gt; "\n",这是错误的。
      6. 使用std::getline(std::cin, input); 然后if(!input.empty()) 不起作用。它可能会卡在EOF 的不定式循环中。

      最后,回到参考资料。您将 Zoo 按值(副本)传递到您的 decide() 函数中。因此,它将动物添加到自己的 Zoo 私有副本中,该副本在离开函数范围时被销毁。因此,main() 中定义的Zoo 对象永远不会被修改。要修复它,请将 void decide(std::string input, Zoo zooInput) 更改为 void decide(std::string input, Zoo&amp; 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
      $ 
      

      【讨论】:

      • 我认为在 SO 上解决和交作业是不合适的。
      • @Al-Muhandis:抱歉,我没上过大学,所以我不知道如何区分一个学习 C++ 的人的作业和编程问题。
      • @Al-Muhandis 他说他正在学习 C++。通常当我读到它时,我不认为“家庭作业”而是一个自学成才的初学者。但这只是我。这个问题一开始就很明显,所以没有必要修复程序的其余部分。
      • 一个关于将动物添加到动物园的程序非常可疑。鉴于这样的怀疑,从我目前在 SO 上看到的情况来看,最好的做法是避免解决和重新发布代码。
      • 哦,没关系。我认为你的意思是它必须是 zoo.end()。哈哈谢谢你。还要感谢您对我的代码的严格分解。这实际上是一个示例,我必须输入而不是复制粘贴我的实际“作业论文”,因为是的,问题出在家庭作业上,但我不想因为作业被困而脱身,请为我解决。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-31
      • 2015-05-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多