首页 > 解决方案 > 更改通过指针传递给函数的对象

问题描述

我需要:

  1. 创建对对象的引用。

  2. 将它传递给调用对象类的构造函数的函数并对对象进行一些计算。

  3. 将对象传递给另一个也用它做一些东西的函数。

我的第二个函数的对象总是空的。

我稍微知道堆栈和堆内存之间的区别以及 new 运算符的使用,但无法处理。我不明白为什么gfunc1结束后没有改变。

#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?

标签: c++pointers

解决方案


如果您想使用指针来“通过引用传递”,那么就这样做:

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()成员函数?


推荐阅读