0

我想从包含在方法中创建的多个对象的方法调用中返回一个signle 对象。

Results calculate() {

    Foo f;
    Bar b;
    ...
    Results r(f, b);
    return r;
}


class Results {

private:
    ?

public:

    Results(Foo& f, Bar& b);

    Foo? getFoo();

    Bar? getBar();

}

a)Results成员变量应该是指针吗?

private:
    Foo* foo;
    Bar* bar;


public:
    Results(Foo& f, Bar& b) {
        this->foo = &f;
        this->bar = &b;
    }

b) 应该getFoo返回FooFoo&还是Foo*

4

5 回答 5

4

使用 C++11 的元组(或 boost's,否则),你基本上是在重新实现它们:

#include <tuple>

std::tuple<Foo, Bar> calculate() {
    Foo f;
    Bar b;
    ...
    return std::make_tuple(f, b);
}

void test() {
    Foo f;
    Bar b;
    std::tie(f, b) = calculate();
}

请注意,这可以很容易地扩展为返回 2 个以上的对象。这就是为什么我使用std::tuple而不是std::pair另一个答案中提到的原因。

于 2013-01-08T13:00:35.310 回答
2

不,不要这样做。因为 incalculate()和是本地对象,当您从此函数返回时,它们将消失Foo fBar b复制fb进入Results.

class Results {
private:
    Foo foo;
    Bar bar;

public:
    Results(const Foo& f, const Bar& b) : foo(f), bar(b) {}

    const Foo &getFoo() const { return foo; }
    const Bar &getBar() const { return bar; }
}

一种更简单的方法是使用 astd::pair并返回它

std::pair<Foo, Bar> calculate() {
    Foo f;
    Bar b;
    ...
    return std::make_pair(f, b);
}
于 2013-01-08T13:00:43.527 回答
1

a) 不会。通过初始化 中的值calculate(),这些变量会在函数完成执行时“死亡”。这样,您之前初始化的指针将指向一个空白空间。

b)考虑到私有成员不是指针,您可以根据需要执行此操作。如果您希望数据“停留”在对象内,您可以使用指针或引用(不管是哪一个)。否则取“正常”变量。

于 2013-01-08T13:00:41.230 回答
0

我仍然有点不确定你想要实现什么,但目前你会遇到麻烦:a 和 b 在计算中的堆栈上,你基本上返回指向它们的指针。但是,一旦计算完成并a超出b范围,您就会有野指针。这很糟糕。
如果您有更多返回值,请创建智能指针并在对象中返回它们。
或者传递指向a和计算的指针,并使用in calculateb在堆上创建对象。new但请注意,您必须自己删除它们,否则最终会导致内存泄漏。所以基本上,如果你有两个以上的对象result,那么添加一个智能指针,比如std::auto_ptror std::shared_ptr(或者如果你不使用 C++11 boost::shared_ptr

于 2013-01-08T13:01:37.783 回答
0

a) 结果成员变量应按值保存。否则,您将返回本地、超出范围的数据的地址(或引用)。

b) getFoo 应该返回对对象的 const 引用,或者在 POD 类型的情况下按值返回。

也就是说,考虑更改您的界面以接受 Foo& 和 Bar& 类型的 i/o 参数,填充内部变量而不返回它们。这将避免返回值的两个副本,否则这是必需的。

你也可以Results用 std::tuple 替换你的类:

std::tuple<Foo,Bar> calculate() {

    Foo f;
    Bar b;
    ...
    return std::tuple(f,b);
}

// client code:
Foo foo;
Bar bar;

std::tie(foo, bar) = calculate();

编辑:如果您不使用 C++11 (for std::tuple),请考虑boost::tuple

于 2013-01-08T13:07:48.840 回答