【问题标题】:out parameters in c++ pass by referencec++中的out参数通过引用传递
【发布时间】:2016-05-13 12:22:39
【问题描述】:

我想在 c++ 中实现类似的东西。这是一个 c# 代码。我想尽可能避免使用原始指针。

class Program
{
    public class Foo
   {
        public int v1;
        public int v2; 
        public Foo(int a, int b)
        {
            v1 =a; v2 =b; 
        }
    };

    public class Bar
    {
        public static void getFoo(out Foo fooObj)
        {
            fooObj = new Foo(1,2);
        }
    };

    static void Main()
    {
        Foo fooObj = null; 
        Bar.getFoo(out fooObj);
        Console.WriteLine("Foo.v1="+fooObj.v1);
        Console.WriteLine("Foo.v2="+fooObj.v2);
    }
}

【问题讨论】:

  • 任何 C++ 教科书或教程都应该解释如何使用引用参数。
  • @Barmar 很少有人(如果有的话)会解释正确的方法(按照 Jose 的回答)。许多人会使用原始指针或对对象的引用,它们在功能上与 C# 版本相当。

标签: c++ pass-by-reference


【解决方案1】:

我尝试将您的 C# 代码转换为 C++。但是,一旦你运行它,你需要对如何使用我在这里使用的所有功能进行适当的研究。 unique_ptr 基本上会为您管理“原始”指针(这是您想要的,一旦超出范围就会释放它)。我添加了一个使用可变参数模板的改进版本,因此您可以传递任意数量的任何类型的参数来动态创建您的 Foo 类。

#include <memory>
#include <iostream>

class Foo
{
public:
    int v1;
    int v2;

    Foo(int a, int b)
    {
        v1 =a; v2 =b;
    }
};

class Bar
{
public:
    // This is what your function looks like in C++
    static void getFoo(std::unique_ptr<Foo>& fooObj)
    {
        fooObj = std::make_unique<Foo>(1, 2);
    }

    // This is a better implementation.
    template<typename ...Args>
    static void getFoo_improved(std::unique_ptr<Foo>& fooObj, Args&&... args)
    {
        fooObj = std::make_unique<Foo>(std::forward<Args>(args)...);
    }

    // This is the one used more often in C++ tho.
    template<typename ...Args>
    static std::unique_ptr<Foo> getFoo_improved_x2(Args&&... args)
    {
        return std::make_unique<Foo>(std::forward<Args>(args)...);
    }
};

int main()
{
    std::unique_ptr<Foo> fooObj = nullptr; //nullptr is not needed tho
    Bar::getFoo(fooObj);

    std::unique_ptr<Foo> fooObj_alt = nullptr; //nullptr is not needed tho
    Bar::getFoo_improved(fooObj_alt, 9, 10);

    //This is as fast as the other two
    auto fooObj_alt_x2 = Bar::getFoo_improved_x2(50, 60);

    std::cout << "Foo.v1=" << fooObj->v1 << std::endl;
    std::cout << "Foo.v2=" << fooObj->v2 << std::endl;

    std::cout << "Foo_alt.v1=" << fooObj_alt->v1 << std::endl;
    std::cout << "Foo_alt.v2=" << fooObj_alt->v2 << std::endl;

    std::cout << "Foo_alt_x2.v1=" << fooObj_alt_x2->v1 << std::endl;
    std::cout << "Foo_alt_x2.v2=" << fooObj_alt_x2->v2 << std::endl;

    return 0;
}

【讨论】:

  • -1,仅代码答案,不解释任何内容,基本上只是在他们没有尝试时将代码扔给 OP
  • @Tas 我希望有人告诉我当我开始使用 C++ 时该看哪里。有时您只是想学习如何用一种语言做某事,而您没有时间阅读 1000 页的书。
  • = nullptr; 在您的 unique_ptr 对象声明中是多余的;他们一开始是空的。恕我直言,它使代码更加混乱。
  • OP 注释:在 C++ 中,更常见的风格是让 getFoo 返回 unique_ptr&lt;Foo&gt; 而不是采用参考参数。与make_unique 函数的实际外观非常相似。
  • @M.M 你是对的,我已经编辑了我的答案以指出这些事实。尽管我从一开始就没有以“正确”的方式做这件事的原因是模仿他的 C# 代码,所以他会更好地理解它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 2012-01-04
  • 2010-10-07
  • 1970-01-01
  • 1970-01-01
  • 2011-10-07
  • 1970-01-01
相关资源
最近更新 更多