如何将一个对象的引用传递给另一个对象并仍然修改该第一个对象?

时间:2017-06-07 21:37:01

标签: c++ string function oop reference

我试图理解引用如何在c ++中工作,所以我用两个不同的对象制作了几个文件。一个是动物,另一个是动物园管理员。我的目标是将动物的参考传递给动物园管理员并让动物园管理员更改动物的名称,并仍然反映在原始动物对象中。如何使用引用完成?以下是我正在使用的文件。

Source.cpp

#include <iostream>
#include <string>
#include "Animal.h"
#include "zookeeper.h"

using namespace std;

int main() {

    Animal animal;
    Animal& animalRef = animal;

    printf("animal's name before it is assigned to a zookeeper: %s\n", animal.getName());

    Zookeeper aZookeeper = Zookeeper(animalRef);
    aZookeeper.changeMyAnimalsName("Fred");

    printf("animal's name after it is assigned to a zookeeper: %s\n", animal.getName());

    //Keep cmd window open
    int j;
    cin >> j;
    return 0;
}

Animal.h

#pragma once
#include <string>

using namespace std;

class Animal {

    string name = "";
    int height = 0;
public:
    string getName() { return name; }
    int getHeight() { return height; }

    void setName(string n) { name = n; }
    void setHeight(int h) { height = h; }
};

zookeeper.cpp

#include "zookeeper.h"

using namespace std;

Zookeeper::Zookeeper(Animal& a) {
    _myAnimal = a;
}

void Zookeeper::changeMyAnimalsName(string newName) {
    _myAnimal.setName(newName);
}

zookeeper.h

#pragma once

#include "Animal.h"

class Zookeeper {
    Animal _myAnimal;
public:
    Zookeeper(Animal& a);
    void changeMyAnimalsName(std::string newName);
};

2 个答案:

答案 0 :(得分:1)

你的推理是正确的,但你最终制作了动物的副本,那里:

False > 0

如果你有:

False

然后你会保留对原始动物的引用,使名称更改能够反映在class Zookeeper { Animal _myAnimal; 中。

之后,您应该将构造函数更改为:

Animal& _myAnimal;

我在那里使用了初始化列表,这对于参考是必不可少的,因为你可以阅读How to initalize the reference member variable of a class?

然而,这还不够。如果您使用了-Wall -Wextra标志,要启用警告,您会看到:

main()

中,我们通常使用std::cout进行打印,如下所示:

Zookeeper(Animal& a) : _myAnimal(a) {}

或者,如果您确实需要使用Source.cc: In function 'int main()': Source.cc:13:88: warning: format '%s' expects argument of type 'char*', but argument 2 has type 'std::__cxx11::string* {aka std::__cxx11::basic_string<char>*}' [-Wformat=] printf("animal's name before it is assigned to a zookeeper: %s\n", animal.getName()); ^ Source.cc:18:87: warning: format '%s' expects argument of type 'char*', but argument 2 has type 'std::__cxx11::string* {aka std::__cxx11::basic_string<char>*}' [-Wformat=] printf("animal's name after it is assigned to a zookeeper: %s\n", animal.getName()); ^ ,那么您可以使用c_str(),它会返回int main() { Animal animal; Animal& animalRef = animal; // not needed, Zookeeper(animal) OK too std::cout << "animal's name before it is assigned to a zookeeper: " << animal.getName() << std::endl; Zookeeper aZookeeper = Zookeeper(animalRef); aZookeeper.changeMyAnimalsName("Fred"); std::cout << "animal's name after it is assigned to a zookeeper: " << animal.getName() << std::endl; return 0; } 的C字符串,如下所示:

printf()

答案 1 :(得分:0)

您的班级Zookeeper定义了_myAnimal类型的数据成员Animal(而不是类型Animal&)。因此,如果在您的构造函数中指定了_myAnimal = a,则a - 虽然是引用 - 会被复制,因为_myAnimal不是引用。 要保持对传递给构造函数的对象的引用,您还需要将数据成员_myAnimal定义为引用:

class Zookeeper {
    Animal &_myAnimal;
public:
    Zookeeper(Animal& a) : _myAnimal(a) { };
    void changeMyAnimalsName(std::string newName);
};