Reputation: 2580
I'm learning C++ and i just have a small problem. I have a class which contains a vector<int>
. From outside this vector<int>
should be accessable, so it should be possible to add/remove/get its elements.
It should not be possible to override the object with a new instance. Here is such an example class (it's minimalized):
class MyClass
{
public:
vector<int>& vec() { return _vec; }
private:
vector<int> _vec;
};
E.g. the following code works:
MyClass x;
x.vec().push_back(0);
x.vec().push_back(7);
x.vec().push_back(9);
cout << c.vec().size() << endl;
But unfortunately the following code also works:
MyClass x;
x.vec() = vector<int>();
I like to disallow this, but i did only find the solution to return a pointer of type vector<int> *
. But i learned pointers are 'evil' and i shouldn't use them directly, i have to use smart pointers. I think for this problem a smart pointer is useless, so i don't know how to solve this simple problem:-/
Or is just a simple pointer the cleanest solution?
best regards
Kevin
-edit-
In general i like to make something that can be used like the follwing C# class:
public class MyClass
{
public List<int> List { get; private set; }
public MyClass()
{
List = new List<int>();
}
}
It's just an example and i just thought about how to make this in C++. Maybe i some cases i have much more complex classes than vector<int>
/List<int>
to include into other classes.
But maybe it is only possible to do this by defining own methods (=interface) to the internal object.
Upvotes: 0
Views: 401
Reputation: 23001
It seems wrong to me that the only acceptable solution is to provide forwarding functions for potentially all the methods in the vector class. So I would like to propose an alternative answer.
Create a small template class publically derived from vector
that hides the operator=
method by making it private.
template<class T>
class immutablevector : public vector<T>
{
private:
immutablevector &operator=(vector<T>);
};
Then in MyClass
, wherever you would have used vector
, use immutablevector
instead.
class MyClass
{
public:
immutablevector<int>& vec() { return _vec; }
private:
immutablevector<int> _vec;
};
Now you can safely access all vector functionality via the vec
method, but you won't be able to assign a new vector instance.
Upvotes: 3
Reputation: 1447
You might want to consider using functions to only expose the functionality you need:
class MyClass
{
public:
void push_back(int value) { _vec.push_back(value); }
size_t size() { return _vec.size(); }
private:
vector<int> _vec;
};
int main()
{
MyClass x;
x.push_back(0);
x.push_back(7);
x.push_back(9);
cout << x.size() << endl;
return 0;
}
Or alternatively just use a plain vector.
Upvotes: 3
Reputation: 155
It's a bit strange how you use the private
identifier.
You set your vector<int>
as private
and then you create a public method that gives direct access to that variable.
You should instead create public methods get()
and push_back()
class MyClass{
private: vector<int> _vec;
public:
vector<int> get(){ return _vec(); }
void push_back(int x) { _vec.push_back(x); }
};
//this will work
MyClass x;
x.push_back(0);
x.push_back(7);
x.push_back(9);
cout<<x.get().size()<<endl;
Now there is not way you to directly modify the private
variable vector<int> _vec
.
Keep in mind you will probably need to instantiate _vec
in MyClass
's constructor.
Upvotes: 3