这个 c++ 代码有什么问题

What is wrong with this c++ code?

本文关键字:什么 问题 代码 c++ 这个      更新时间:2023-10-16

如您所见,我是C++新手,但我不明白为什么y = new Person()函数foo是错误的。感谢您的帮助。

我收到此错误:

错误:与"y = (((Person*(运算符新(32u(("中的"运算符="不匹配, (, (('

更新:

我将在今晚之前接受支持率最高的答案,或者更令人信服的答案。

和我朋友之间的争论是,函数foo是否可以改变对象并在函数外部传播变化,就像做y = Person()时一样,那么brother也会改变还是会保持不变?.

法典:

#include <iostream>
using namespace std;
 class Person {
   public:  
    int age;
    char name[25];
    Person() {
            age = 0;
    }
};
void foo(Person &y)
{
    y = new Person();
}
int main()
{
    Person *brother = new Person();
    brother->age = 20;
    cout << "age = " << brother->age << endl;
    foo(*brother);
    cout << "age = " << brother->age << endl;
    return 0;
} 

你可能来自一种语言,对象只能用new创建。在C++,情况并非如此。除非你真的需要它,否则你不应该使用新的。只需将其创建为普通变量:

#include <iostream>
#include <string>
class Person
{
public:
    unsigned age;
    std::string name;
    Person(unsigned age, std::string name)
        : age(age)
        , name(std::move(name)) // move is C++11
    {}
};
int main()
{
    Person brother(8, "Tim John");
    std::cout << "age = " << brother.age << 'n';
    // Edit regarding the question in the comments:
    brother = Person(16, "John Tim");
    std::cout << "age = " << brother.age << 'n';
}

您对上述代码的问题是 new 返回一个指针,并且您正在尝试将指针分配给 Person,这显然不起作用。

void foo(Person &y)
{
    y = new Person();
}

y是引用,而不是指针。要重新分配给y,您需要使用

y = Person();

但是,如果您真的想分配一个新人,则可以使用

void foo(Person* &y) // reference to pointer to Person

使用引用,您基本上说您修改了调用站点的值。

请注意,您当前的代码泄漏。如果你有一个要自己管理的裸指针,你必须先删除它:

void foo (Person*& y)
{
    delete y;
    y = new Person;
}

但如您所见,代码在不知道目标的情况下已经变得混乱。在呼叫站点delete,或者在呼叫foo(...)之前根本不分配y可能更合适。

另请注意,改用foo (Person* y)并不能解决在调用站点new的问题:

void foo (Person *y) 
{
    y = new Person();
}

这当然可以编译,但只修改foo自己的y变量。调用方将具有未更改的指针。

请注意,最好使用值类型或智能指针,因为编写手动管理内存的异常安全代码并非易事。

在函数 foo 中,该行应该是

y = Person();

y不是指针。

编辑:实际上,这是错误的答案(即使你目前被乔恩接受(。您不应该混合堆和堆栈,并导致这样的内存泄漏。正确的方法是直接更改对象的成员。赋值运算符 (operator=( 将更改对象的成员。因为问题不是关于混合堆和堆栈,而是关于更改对象,所以代码可以更好地解释这个问题。请注意,这里没有使问题复杂化的new

void foo(Person &y)
{
    y = Person();
}
int main()
{
    Person brother;
    brother.age = 20;
    ...
    foo(brother);
    ...
    return 0;
}

y = Person()后,brother对象将被更改,因为y brother并且赋值运算符更改了对象的成员。

在处理指针操作时,切勿将自己与&*运算符混淆。"&"用于不同的上下文。 &,当在函数的形式参数中使用是引用参数时,这个运算符通过引用(通过其地址(传递变量。但是,变量y仍然像普通变量一样工作。
所以这段代码..

void foo(Person &y) 
{ 
y = new Person(); 
}

不会工作,因为new Person()正在解析指向变量的指针。例如

int * intp = new int;
int variable = intp;

这就是这里正在发生的事情。引用参数的作用类似于变量,但实际上可以直接访问变量,因为它是通过引用操作进行的调用。编写此函数的正确方法如下所示

 void foo(Person ** y) 
{ 
*y = new Person(); 
}

也就是说,如果您尝试通过函数初始化类指针。正如库克所说,这是人们在 c++ 中产生的误解,他们使用的语言编程需要new键才能创建对象/变量。来源
http://fredosaurus.com/notes-cpp/functions/refparams.html

您正在尝试在引用上调用"new"运算符。 而"new"仅与指针一起使用。传递给void foo( )函数

 Person* 

而不是

Person&

一点解释:

传递参数的正确方法取决于你必须做什么!!

如果你想对传递给函数的对象产生副作用,正确的方法是声明:

void foo(Person& person)

对象人可以被修改。如果你不想对对象产生副作用,你必须声明对象'const':

void foo(const Person& person)

const 意味着即使传递引用,也无法修改方法中的对象。

然后你可以传递一个指针:

void foo(Person* person)

在这里,您可以修改"person"指向的对象,但您拥有原始指针的副本。

传递参数的最后一种方法是:

void foo(Person*& person)

这里有一个原始指针的别名。 alias 表示"具有不同名称的同一指针">