我需要:
创建对对象的引用。
将其传递给一个调用该对象的类的构造函数并对该对象进行一些计算的函数。
将该对象传递给另一个函数,该函数也可以使它起作用。
我转到第二个函数的对象始终为空。
我稍微了解堆栈内存和堆内存以及使用new运算符之间的区别,但是无法处理。我不明白为什么func1结束后g
不会改变。
#include <iostream>
class Grid
{
public:
int a;
Grid()
{
a = 2;
}
};
void func1(Grid * g);
void func2(Grid * g);
int
main ()
{
Grid g;
func1(&g);
func2(&g);
}
void
func1 (Grid * g)
{
g = new Grid();
g->a = 5;
}
void
func2 (Grid * g)
{
std::cout << g->a << std::endl;
}
如何在func2 5中使输出变为2?
答案 0 :(得分:3)
如果要使用指针“通过引用传递”,则只需执行以下操作:
void
func1 (Grid * g)
{
g->a = 5;
}
void
func2 (const Grid * g)
{
std::cout << g->a << std::endl;
}
int
main ()
{
Grid g;
func1(&g);
func2(&g);
}
当前您正在使用一个指针(并记住该指针本身是通过值传递的),然后使用一个指向动态分配的新指针的指针覆盖该指针的本地作用域副本 Grid
个对象。您在该对象上设置了一个属性,然后将其泄漏。
在C ++中,我们通常使用实际的引用来代替,这可能更清楚(尽管在调用站点上可能不那么清楚!):
void
func1 (Grid& g)
{
g.a = 5;
}
void
func2 (const Grid& g)
{
std::cout << g.a << std::endl;
}
int
main ()
{
Grid g;
func1(g);
func2(g);
}
至于这一点:
将其传递给调用对象类的构造函数的函数
该对象已被构造。如果您确实想以这种方式“重置”它,则可以从一个新的临时对象进行复制分配:
void
func1 (Grid& g)
{
g = Grid();
g.a = 5;
}
但是我建议您重新考虑您是否真的想要/需要像这样重置对象。而且,如果您愿意,也许是一个不错的reset()
成员函数?
答案 1 :(得分:3)
这是使用指针的另一种可能性
Grid * func1();
void func2(Grid * g);
int main ()
{
Grid * g = func1();
func2(g);
}
Grid * func1 ()
{
Grid * g = new Grid();
g->a = 5;
return g;
}
void func2 (Grid * g)
{
std::cout << g->a << std::endl;
}
答案 2 :(得分:1)
实际上,当您使用Delete
时,您更改了指针的值。
但是无论如何,我认为您可以轻松得多。例如:
new
编辑:
当然,您必须像这样呼叫void func(Grid & g)
{
g.a = 5;
}
:
func()
我希望它能有所帮助;
答案 3 :(得分:1)
为了帮助您想象这个,我将这样写:
numerate [(), (), (), (), ()]
-- [1, 2, 3, 4, 5]
上面的代码将与其他代码完全相同(在64位系统上)。显然这太可怕了,绝不应该使用上面的代码,但是像这样写出来可能会帮助您理解指针。