【问题标题】:Passing an Array of Objects into a Function将对象数组传递给函数
【发布时间】:2020-12-22 21:44:55
【问题描述】:

我有一个类将 object.name 定义为“Ben”,object.favNum 定义为 25。

我还有一个数组(名字)来存储这个类的 5 个对象。

在输出数组中对象的属性之前,我使用指针表示法将 names[0].name 的值更改为“Jim”,将 names[0].favNum 的值更改为 40。

这是我的代码:

#include<iostream>

class Person {
public:
    std::string name = "Ben";
    int favNum = 25;
};


int main()
{
    Person names[5];

    Person *ptr = &names[0];


    // Changing Values
    (ptr + 0)->name = "Jim";
    (ptr + 0)->favNum = 40;


    for (int i = 0; i < 5; i++) 
    {
        std::cout << (std::string) (ptr + i)->name   << std::endl;
        std::cout << (int) (ptr + i)->favNum << std::endl << std::endl;
    }

    system("pause>0");
}

输出:

Jim
40

Ben
25

Ben
25

Ben
25

Ben
25

在我有“更改值”注释的地方,我想用一个函数替换这两行。 该函数将能够像我对 2 行所做的那样更改值。 这就是我遇到问题的地方。

我正在努力弄清楚将函数声明为什么类型、如何传递指针、如何接收指针以及如何更改函数中数组中对象的值。

【问题讨论】:

  • 有什么理由在 C++ 代码中使用原始数组和原始指针?使用std::array&lt;Person,5&gt; 甚至std::vector&lt;person&gt;,您会变得更好、更轻松。
  • 您不需要将事物转换为已有的类型。对代码进行强制转换是引入难以发现的错误的可靠方法。
  • 另外,(ptr + i)-&gt;name 通常写成ptr[i].name
  • @Ben 有很好的文档资料:en.cppreference.com/w/cpp/container “昨天开始使用数组和指针。” 如果您想了解如何使用,那绝对是您可以使用的最糟糕的起点用 C++ 编写代码。
  • 这里可以避免指针。例如,只需使用names[0] = {"Jim", 40};

标签: c++ arrays function class object


【解决方案1】:

这就是您的代码在“real” c++ 中的样子(值的设置将在构造函数中完成或使用setNameAndFavNum() 函数):

#include <array>
#include <iostream>

struct Person {
public:
    Person(const std::string& name_ = "Ben", int favNum_ = 25) : name(name_), favNum(favNum_) {};
    void setNameAndFavNum(const std::string& name_, int favNum_) {
        name = name_;
        favNum = favNum_;
    };

    std::string name;
    int favNum;
};    

int main() {
    std::array<Person, 5> names;


    // Changing Values
    names[0].setNameAndFavNum("Jim", 40);

    // Alternatively you can use the constructor and implicit copy constructor
    // names[0] = {"Jim", 40};

    for (int i = 0; i < names.size(); i++)  {
        std::cout << names[i].name << std::endl;
        std::cout << names[i].favNum << std::endl << std::endl;
    }
}

在编写 C++ 代码时,您不应该乱用指针和原始值。

【讨论】:

  • @Jan 这样更好吗?
  • 是的,这样更好,但是setNameAndFavNum和构造函数仍然没有必要。两者都可以替换为默认定义的聚合初始化和赋值。
  • @JanSchultke 我添加了setNameAndFavNum () 来演示函数的使用,这是 OP 最初要求的。
  • 技术上operator= 也是一个函数 :) 我明白你的意思,但是 OP 将这些行提取到函数中的动机似乎是使代码更简洁。从 OP 对指针的使用来看,他们不是最有经验的 C++ 开发人员。在这种情况下,推荐一种更简单、更规范的方式对他们的帮助远大于为他们提供他们所要求的。如果没有人告诉你使用引用,你可能会一直误用指针。
【解决方案2】:

我建议不要使用指针,除非你真的需要指针。

// use references instead
void change(Person &person) {
    person.name = "Jim";
    person.favNum = 40;
};

int main()
{
    Person names[5];

    change(names[0]);

    // ...
}

编写此类函数的适当方法是使用引用。引用类似于指针,但不能是nullptr。在您的情况下,您不需要可空性,您只需要编辑 Person 而不复制它。

您可能希望 change() 是参数化的:

// use references instead
void change(Person &person, std::string name, int favNum) {
    person.name = std::move(name);
    person.favNum = favNum;
}

但是现在您正在使用此函数分配Person 的所有成员,这使其毫无意义。如果你分配Person 会更简单。为什么不使用struct 和聚合初始化:

struct Person {
    std::string name = "Ben";
    int favNum = 25;
};

int main()
{
    Person names[5];

    names[0] = {"Jim", 40};

    // ...
}

顺便说一句,你在这里做的事情是不必要的复杂:

(ptr + 0)->name = "Jim";

// this is equivalent to
ptr[0].name = "Jim";

// this is equivalent to
ptr->name = "Jim";

【讨论】:

    猜你喜欢
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多