Reputation: 241
for the below code demo, I send a reference into a class, and add some items to the vector, then return the vector, I think there is copy issue in the assignment test = a.return_data() in the main function, is there some method to improve the efficiency?
#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;
class A
{
public:
A(vector<int> &a);
void additem(int c);
vector<int> return_data();
private:
vector<int> d;
};
A::A(vector<int> &a)
{
d = a;
}
void A::additem(int c)
{
d.push_back(c);
}
vector<int> A::return_data()
{
return d;
}
void main()
{
vector<int> test;
for(int i=0; i<10; i++)
{
test.push_back(i);
}
cout << test.size() << endl;
A a(test);
a.additem(10);
test = a.return_data();
cout << test.size() << endl;
}
Upvotes: 1
Views: 178
Reputation: 172934
You could hold a reference member in the class,
class A
{
... ...
private:
vector<int>& d;
};
And then use member initializer lists to initialize it in ctor,
A::A(vector<int> &a) : d(a) {}
And then no need to use return_data()
anymore,
void main()
{
vector<int> test;
for(int i=0; i<10; i++)
{
test.push_back(i);
}
cout << test.size() << endl;
A a(test);
a.additem(10);
// test = a.return_data();
cout << test.size() << endl;
}
NOTE: Make sure the reference will not be invalid.
Upvotes: 3
Reputation: 43662
If you don't need your class to exclusively own the vector you might simply get away with a reference (and render return_data
obsolete)
class A {
public:
A(vector<int> &a);
void additem(int c);
private:
vector<int>& d; // Just store a reference
};
A::A(vector<int> &a) : d(a) {}
int main() {
vector<int> test;
for (int i = 0; i<10; i++) {
test.push_back(i);
}
cout << test.size() << endl;
A a(test);
a.additem(10);
cout << test.size() << endl;
}
Anyway, if you do need to deal with ownership (following the rule of zero) you could use unique_ptr
s and move them around
class A {
public:
A(unique_ptr<vector<int>>&& a);
void additem(int c);
unique_ptr<vector<int>> return_data();
private:
unique_ptr<vector<int>> d; // Unique owner of the vector
};
A::A(unique_ptr<vector<int>>&& a) :
d(forward<unique_ptr<vector<int>>>(a))
{}
unique_ptr<vector<int>> A::return_data() {
return move(d); // Moves the member vector (can no longer be used)
}
int main() {
unique_ptr<vector<int>> test = make_unique<vector<int>>();;
for (int i = 0; i<10; i++) {
test->push_back(i);
}
cout << test->size() << endl;
A a(move(test));
a.additem(10);
test = a.return_data();
cout << test->size() << endl;
}
In both cases no copies are necessary and thus even for large vectors it should prove to be faster than your approach. Keep in mind that the latter approach is one-shot-only, i.e. you don't get to return multiple copies of the vector.
Upvotes: 1
Reputation: 3995
Instead of return_data you could simply let the user of the function pass an argument, which you will take by reference.
void get_data(std::vector<int> &vec)
{
//Now you can either copy or move
vec = d;
//or
vec = std::move(d);
}
You cannot always be sure, that the element of the reference being hold in the class still exists later.
Upvotes: 0