设置成员函数,授予成员

时间:2017-02-14 22:58:44

标签: c++

我有一个类,我需要以const方式访问一些巨大的对象。为此,我有getABC()成员函数将这些对象复制到外部世界。是否可以直接访问它们,因为在我的情况下复制操作非常慢? shared_ptr会更好,我也想避免让元组只在getABC()中返回它们

#include <iostream>
#include <vector>

using namespace std;

class foo {
private:
    int a;
    vector<int> b; // HUGE OBJECT 
    vector<int> c; // HUGE OBJECT
public:
    foo(int a_, vector<int> b_, vector<int> c_) : a(a_), b(b_), c(c_) { }
    void printfoo() {
        cout << "a   = " << a << endl;
        cout << "b   = ";
        for(auto v:b) {
            cout << v << " ";
        }
        cout << endl;
        cout << "c   = ";
        for(auto v:c) {
            cout << v << " ";
        }
        cout << endl;
    }
    void getABC(int & a_in, vector<int> & b_in, vector<int> & c_in ) const {
        a_in = a;
        b_in = b; // SLOW
        c_in = c; // SLOW
    }

};


int main() {

    int in = 4;
    vector<int> inA {1, 2, 3, 5};
    vector<int> inB {2, 2, 3, 5};

    foo bar(in, inA, inB);
    bar.printfoo();

//  GET THE MEMBERS
    int out = 0;
    vector<int> outA;
    vector<int> outB;
    bar.getABC(out, outA, outB);


//  PRINT 
    cout << "OUT = " << out;
    cout << "\nOUTA = ";
    for(auto const &v : outA ) {
        cout << v << " ";
    }
    cout << endl;
    cout << "OUTB = ";
    for(auto const &v : outA ) {
        cout << v << " ";
    }
    cout << endl;

    return 0;
}

2 个答案:

答案 0 :(得分:0)

你可以有3个独立的函数来返回const引用(int不需要):

class foo {
    ...
    int getA() const                { return a; }
    const vector<int>& getB() const { return b; }
    const vector<int>& getC() const { return c; }
};

这些甚至可以由编译器内联,因此您不需要将它们实际放在任何地方。只要您需要bar.getB(),就可以致电b。即使没有内联,您也很可能不会注意到性能损失。

答案 1 :(得分:0)

  

我想避免让元组只是在getABC()

中返回它们

为什么呢?这似乎是返回对多个数据的引用最直接的方法:

tuple<const int&, const vector<int>&, const vector<int>&> getABC() const
{ return std::make_tuple(std::cref(a), std::cref(b), std::cref(c)); }


auto refs = bar.getABC();
for (auto& x : std::get<1>(refs))
  // ...

或者创建一个命名结构来代替:

struct DataRefs {
  int a;
  const std::vector<int>& b;
  const std::vector<int>& c;
};

DataRefs getABC() const  { return { a, b, c }; }

这样做的好处是您不需要使用std::get<N>来访问成员,并且可以使用合理的名称:

auto refs = bar.getABC();
for (auto& x : refs.b)
  // ...

从你的评论中你可能想要这样的东西,但这将是一个愚蠢的界面:

void getABC(const int*& pa, const std::vector<int>*& pb, const std::vector<int>*& pc) const
{
  pa = &a;
  pb = &b;
  pc = &c;
}

您可以这样使用:

int* a;
std::vector<int>* b;
std::vector<int>* c;
bar.getABC(a, b, c);
for (auto& x : *b)
  // ...

正如你所看到的,这对于调用者来说更加冗长,而且只是丑陋而不是惯用的C ++。

或者您可以将数据移动到单独的子对象中:

class foo
{
  struct data
  {
    int a;
    std::vector<int> b;
    std::vector<int> c;
  };
  data m_data;

public:
  const data& getData() const { return m_data; };
};

auto& refs = bar.getData();
for (auto& x : refs.b)
  // ...