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

时间:2012-02-29 10:25:46

标签: c++

正如您所见,我是C ++的新手,但我无法理解函数y = new Person()foo为何错误。谢谢你的帮助。

我收到了这个错误:

  

错误:'y =(((Person *)operator new(32u))中'operator ='不匹配,   (,))'

UPDATE:

我将接受今晚最赞成的答案或更有说服力的答案。

我和我的朋友之间的争论是函数foo可以改变对象并将更改传播到函数之外,就像执行y = Person()时一样,然后brother也会改变或将它改变保持不变?

CODE:

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

5 个答案:

答案 0 :(得分:7)

你可能来自一种语言,只能用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的指针,这显然无法工作。

答案 1 :(得分:4)

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,或者在调用y之前根本不分配foo(...)

另请注意,使用foo (Person* y)代替解决调用网站new的问题:

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

这当然是编译,但只修改foo自己的y变量。调用者将有一个未更改的指针。

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

答案 2 :(得分:2)

在函数foo中,行应为

y = Person();

y不是指针。

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

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

int main()
{
    Person brother;
    brother.age = 20;

    ...
    foo(brother);
    ...

    return 0;
}

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

答案 3 :(得分:2)

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

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

无效,因为new Person()正在解析指向变量的指针。 例如,

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

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

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

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

答案 4 :(得分:1)

您尝试在引用上调用“new”运算符。而“新”只用于指针。 传递给void foo( )函数

 Person* 

而不是

Person&

一点解释:

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

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

void foo(Person& person)

对象人可以修改.. 如果你不想对对象做副作用,你必须声明对象'const':

void foo(const Person& person)

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

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

void foo(Person* person)

在这里你可以修改“人”指向的对象,但是你有一个原始指针的副本。

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

void foo(Person*& person)

这里你有一个原始指针的别名。别名表示“具有不同名称的相同指针”