正如您所见,我是C ++的新手,但我无法理解函数y = new Person()
中foo
为何错误。谢谢你的帮助。
我收到了这个错误:
错误:'y =(((Person *)operator new(32u))中'operator ='不匹配, (,))'
我将接受今晚最赞成的答案或更有说服力的答案。
我和我的朋友之间的争论是函数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;
}
答案 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)
这里你有一个原始指针的别名。别名表示“具有不同名称的相同指针”