在单个返回对象中组合多个对象

时间:2013-01-08 12:52:23

标签: c++ oop pointers reference

我想从方法调用中返回一个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*

5 个答案:

答案 0 :(得分:4)

使用C ++ 11的元组(或者提升,否则),你基本上是重新实现它们:

#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

答案 1 :(得分:2)

不,不要这样做。因为在calculate()中,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; }
}

更简单的方法是使用std::pair并将其返回

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

答案 2 :(得分:1)

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

b)考虑到私人成员不是指针,你可以根据需要这样做。如果您希望数据“保留”在对象内部,您可以使用指针或引用(无关紧要)。否则采取“正常”变量。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

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

也就是说,考虑改变你的接口以接受Foo&amp;类型的i / o参数。和Bar&amp;,填充内部变量而不返回它们。这样可以避免返回值的两个副本,否则这是必要的。

您也可以用std :: tuple替换Results类:

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(对于std::tuple),请考虑使用boost::tuple