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

标签 c++ string function oop reference

我试图了解引用在 C++ 中的工作方式,因此我制作了两个包含两个不同对象的文件。一个是动物,另一个是动物园管理员。我的目标是将动物的引用传递给动物园管理员并让动物园管理员更改动物的名称,并且仍然反射(reflect)在原始动物对象中。这是如何使用引用完成的?这是我正在使用的文件。

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

动物.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; }
};

动物园管理员.cpp

#include "zookeeper.h"

using namespace std;

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

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

动物园管理员.h

#pragma once

#include "Animal.h"

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

最佳答案

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

class Zookeeper {
    Animal _myAnimal;

如果你有:

Animal& _myAnimal;

然后您将保留对原始动物的引用,使名称更改可以反射(reflect)在 main() 中。

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

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

我在其中使用了一个初始化列表,这对于引用是必不可少的,您可以在 How to initalize the reference member variable of a class? 中阅读


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

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());
                                                                                       ^

我们通常打印 std::cout ,像这样:

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

或者,如果你真的需要使用 printf(),那么你可以使用 c_str() ,它返回 std::string 的 C 字符串,如下所示:

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

关于c++ - 如何将一个对象的引用传递给另一个对象并仍然修改第一个对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44423190/

相关文章:

function - 使用多个参数从.ps1运行PowerShell的函数

c++ - 将 C++ 函数名称打印到 C 而不进行修饰

安卓NDK : How to get screen resolution in native binary?

c++ - 将数据发送到另一个 C++ 程序

c++ - 无法在 ubuntu 12.04 64 位中使用 gloox 库

java - 将多个字符串组合成一个字符串,然后可以将其分离为原始字符串的智能方法?

C char数组,奇怪的字符

c++ - 从并发关联容器中删除 (concurrent_unordered_map)

C - 加载包含指向指针的指针的结构

c++ - 在类函数中重载 "+="时使用 "+"?