In C++ is always better to keep data of a class as private members.
If a class has a vector as member is better to put it as a private or public member?
If I have a vector as private member I cannot easily access to the member function of the vector. So I have to design the class with a method for every function I need to access the vector methods?
Example given:
class MyClass{
private:
std::vector<int> _myints;
public:
get_SizeMyints(){return _myints.size();}
add_IntToMyints(int x){_myints.push_back(x));
};
or is better to keep the vector public and call MyClass._myints.push_back(x)?
---------------------edit--------------
and just for clarity for what is needed this question:
snake.h:
enum directions{UP, DOWN, RIGHT, LEFT, IN, OUT, FW, RW };
class Snake
{
private:
enum directions head_dir;
int cubes_taken;
float score;
struct_color snake_color;
V4 head_pos;
public:
std::vector<Polygon4> p_list; //the public vector which should be private...
Snake();
V4 get_head_pos();
Polygon4 create_cube(V4 point);
void initialize_snake();
void move(directions);
void set_head_dir(directions dir);
directions get_head_dir();
void sum_cubes_taken(int x);
int get_cube_taken();
void sum_score(float x);
float get_score();
void set_snake_color();
};
so now I know how to change the code.
btw... a question, if I need to copy the vector in an other class like this: GlBox.p_list = Snake.p_list (works if are private) what will be an efficent method if they where private?
Running a for cycle to copy the the elements and pusshing back them in the GLBox.p_list seems a bit inefficent to me (but may be just an impression) :(
If it doesn't matter if someone comes along and empties the vector or rearranges all it's elements, then make it public. If it matters, then yes, you should make it protected/private, and make public wrappers like you have. [Edit] Since you say "it's a snake", that means it'd be bad if someone came and removed or replaced bits. Ergo, you should make it protected or private. [/Edit]
You can simplify a lot of them:
MyClass {
private:
std::vector<int> _myints;
public:
const std::vector<int>& get_ints() const {return _myints;}
add_IntToMyints(int x){_myints.push_back(x));
};
That get_ints() function will allow someone to look at the vector all they want, but won't let them change anything. However, better practice is to encapsulate the vector entirely. This will allow you to replace the vector with a deque or list or something else later on. You can get the size with std::distance(myobj.ints_begin(), myobj.ints_end());
MyClass {
private:
std::vector<int> _myints;
public:
typedef std::vector<int>::const_iterator const_iterator;
const_iterator ints_begin() const {return _myints.begin();}
const_iterator ints_end() const {return _myints.end();}
add_IntToMyints(int x){_myints.push_back(x));
};
For good encapsulation, you should keep your vector private.
Your question is not very concrete, so here's an answer in the same spirit:
Generally, your classes should be designed to express a particular concept and functionality. They should not just hand through another member class. If you find yourself replicating all the interface functions of a member object, something is wrong.
Maybe sometimes you really just need a collection of other things. In that case, consider a plain old aggregate, or even a tuple. But if you're designing a proper class, make the interface meaningful to the task at hand, and hide the implementation. So the main question here is, why do you need to expose the vector itself? What is its role in the class? What does its emptiness signify in terms of the semantics of your class?
Find the appropriate idioms and ideas to design a minimal, modular interface for your class, and the question might just go away by itself.
(One more idea: If for example you have some range-based needs, consider exposing a template member function accepting a pair of iterators. That way you leverage the power of generic algorithms without depending on the choice of container.)
Normally, good coding practice is to keep your data members private or protected, and provide whatever public methods will be needed to access them. Not all the methods of (in this case) vector, just what will be useful for your application.
That depends on your class's purpose. If you're trying simply trying to wrap the vector and want to use it as a vector you could make an argument for making the vector public.
Generally speaking I would suggest making it private and providing an appropriate interface to manipulate the container. Additionally this lets you change the container under the hood if a different container would ever be more appropriate (as long as you don't tie your public interface to the container type).
Further as an aside, avoid names that begin with underscores as there are some such identifiers reserved for the implementation and it's safer to just avoid all of them rather than trying to remember the rules in all cases.
A point to realize is that making the std::vector private is only half of the story when it comes to good encapsulation. For example, if you have:
class MyClass {
public:
// Constructors, other member functions, etc.
int getIntAt(int index) const;
private:
std::vector<int> myInts_;
};
...then arguably, this is no better than just making myInts_ public. Either way, clients will write code using MyClass which is dependent on the fact that the underlying representation requires the use of a std::vector. This means that in the future, if you decide that a more efficient implementation would utilize a std::list instead:
class MyClass {
public:
// Constructors, other member functions, etc.
int getIntAt(int index) const; // whoops!
private:
std::list<int> myInts_;
};
...now you have a problem. Since you can't access into a std::list by index, you would either have to get rid of getIntAt, or implement getIntAt using a loop. Neither option is good; in the first case, you now have clients with code that doesn't compile. In the second case, you now have clients with code that just silently became less efficient.
This is the danger of exposing any public member functions which are specific to your choice of implementation. It's important to keep flexibility/future maintenance in mind when designing your class interface. There are a number of ways you could do this with your particular example; see Mooing Duck's answer for one such interface that exposes iterators.
Or, if you would like to maximize code readability, you could design the interface around what MyClass logically represents; in your case, a snake:
class MyClass {
public:
// Constructors, etc.
void addToHead(int value);
void addToTail(int value);
void removeFromHead();
void removeFromTail();
private:
// implementation details which the client shouldn't care about
};
This offers an abstraction of a snake object in your program, and the simplified interface gives you the flexibility to choose whatever implementation suits it best. And if the situation arises, you can always change that implementation without breaking client code.
Theoretically in Object Oriented Programming any attributes should be private and gain access to them via public methods such as Get() and Set().
I think you question is not complete, but what I understand from what you're trying to achieve you need to inherit from std::vector and extend its functionality, to both satisfy your fast access needs and not messing around with encapsulation. (Consider reading on "Inheritance" first from any C++ book, or other OO language)
Having said that, your code might look as following:
class MyClass : public std::vector<int>
{
//whatever else you need goes here
}
int main(void)
{
MyClass var;
var.push_back(3);
int size = var.size(); // size will be 1
}
Hope this answered your question
Related
I've got some class - lets call it MyMutableClass, which implements MutableInterface.
class MutableInterface {
public:
void setMyPreciousData(int value);
int getMyPreciousData() const;
.... //and so on
};
However there is a huge part of code, which should not change the state this class instance, but it need to have a read access.
How to do it in the most polite manner? Should I create an additional ImmutableInterfaces, with getters only and inherits it by MutableInterface? Then I can choose, which one will be passed to another parts of code.
Second option would be to create another class, which object would encapsulate the MutableInterface implementation and provide an access only to a subset of its methods. Is that better?
Is there some well-known patter, which I'm not aware of?
This won't be what you want to hear, but I think it's important to be said in this case.
Inheritance describes a 'is kind of' interface. The derived thing 'is a kind of' the base thing.
A const thing is not 'a kind of' mutable thing. It's an immutable thing.
A mutable thing is not 'a kind of' immutable thing. It's a thing which happens to be mutable.
Mutability is a property of the thing, not a specialisation.
Therefore, inheritance is the wrong model and this is why in c++, constness is a property, not an interface.
If you really must hide the fact that sometimes a thing is mutable (one wonders why), then as mentioned in the comments, you probably want some kind of proxy view class, such as:
// this is the actual thing
struct the_thing
{
void change_me();
int see_me() const;
};
// and this is the proxy
struct read_only_thing_view
{
int see_me() const { return _reference.see_me(); }
the_thing& _referent;
};
I'm curious if that's proper way of assignement
class Foo {
int x_;
public:
int & x() {
return x_;
}
};
My teacher is making assignement like that: obj.x() = 5;
But IMO that's not the proper way of doing it, its not obvious and it would be better to use setter here. Is that violation of clear and clean code ? If we take rule that we should read the code like a book that code is bad, am I right ? Can anyone tell me if am I right ? :)
IMO, this code is not a good practice in terms of evolution. If you need to provide some changes checking, formatting, you have to refactor your class API which can become a problem with time.
Having set_x() would be a way cleaner. Moreover, it will allow you to have checking mechanics in your setter.
a proper getter get_x() or x() could also apply some logic (format, anything...) before returning. In your case, you should return int instead of int& since setter should be used for modification (no direct modification allowed).
And truly speaking, this code doesn't really make sense... it returns a reference on a property making it fully modifiable. Why not having directly a public property then ? And avoid creating an additional method ?
Do you want control or not on your data? If you think so, then you probably want a proper getter and setter. If not, you probably don't need a method, just make it public.
To conclude, I would say you are right, because the way you see it would make it better over the time, prone to non-breaking change, better to read.
As the UNIX philosophy mentions : "Rule of Clarity: Clarity is better than cleverness."
Assuming that x() happens to be public (or protected) member the function effectively exposes an implementation: the is an int held somewhere. Whether that is good or bad depends on context and as it stands there is very little context.
For example, if x() were actually spelled operator[](Key key) and part of a container class with subscript operator like std::vector<T> (in which case Key would really be std::size_t) or std::map<Key, Value> the use of returning a [non-const] reference is quite reasonable.
On the other hand, if the advice is to have such functions for essentially all members in a class, it is a rather bad idea as this access essentially allows uncontrolled access to the class's state. Having access functions for all members is generally and indication that there is no abstraction, too: having setters/getters for members tends to be an indication that the class is actually just an aggregate of values and a struct with all public members would likely serve the purpose as well, if not better. Actual abstractions where access to the data matters tend to expose an interface which is independent of its actual representation.
In this example, the effect of returning a (non-const) reference is the same as if you made the variable public. Any encapsulation is broken. However, that is not a bad thing by default. A case where this can help a lot is when the variable is part of a complicated structure and you want to provide an easy interface to that variable. For example
class Foo {
std::vector<std::list<std::pair<int,int>>> values;
public:
int& getFirstAt(int i){
return values[i].[0].first;
}
};
Now you have an easy access to the first element of the first element at position i and dont need to write the full expression every time.
Or your class might use some container internally, but what container it is should be a private detail, then instead of exposing the full container, you could expose references to the elements:
class Bar {
std::vector<int> values; // vector is private!!
public:
int& at(int i){ // accessing elements is public
return values.at(i);
}
};
In general such a code confuses readers.
obj.x() = 5;
However it is not rare to meet for example the following code
std::vector<int> v = { 1, 0 };
v.back() = 2;
It is a drawback of the C++ language.
In C# this drawback was avoided by introducing properties.
As for this particular example it would be better to use a getter and a setter.
For example
class Foo {
int x_;
public:
int get_value() const { return x_; }
void set_value( int value ) { x_ = value; }
};
In this case the interface can be kept while the realization can be changed.
I'm in a situation where I have a class, let's call it Generic. This class has members and attributes, and I plan to use it in a std::vector<Generic> or similar, processing several instances of this class.
Also, I want to specialize this class, the only difference between the generic and specialized objects would be a private method, which does not access any member of the class (but is called by other methods). My first idea was to simply declare it virtual and overload it in specialized classes like this:
class Generic
{
// all other members and attributes
private:
virtual float specialFunc(float x) const =0;
};
class Specialized_one : public Generic
{
private:
virtual float specialFunc(float x) const{ return x;}
};
class Specialized_two : public Generic
{
private:
virtual float specialFunc(float x) const{ return 2*x; }
}
And thus I guess I would have to use a std::vector<Generic*>, and create and destroy the objects dynamically.
A friend suggested me using a std::function<> attribute for my Generic class, and give the specialFunc as an argument to the constructor but I am not sure how to do it properly.
What would be the advantages and drawbacks of these two approaches, and are there other (better ?) ways to do the same thing ? I'm quite curious about it.
For the details, the specialization of each object I instantiate would be determined at runtime, depending on user input. And I might end up with a lot of these objects (not yet sure how many), so I would like to avoid any unnecessary overhead.
virtual functions and overloading model an is-a relationship while std::function models a has-a relationship.
Which one to use depends on your specific use case.
Using std::function is perhaps more flexible as you can easily modify the functionality without introducing new types.
Performance should not be the main decision point here unless this code is provably (i.e. you measured it) the tight loop bottleneck in your program.
First of all, let's throw performance out the window.
If you use virtual functions, as you stated, you may end up with a lot of classes with the same interface:
class generic {
virtual f(float x);
};
class spec1 : public generic {
virtual f(float x);
};
class spec2 : public generic {
virtual f(float x);
};
Using std::function<void(float)> as a member would allow you to avoid all the specializations:
class meaningful_class_name {
std::function<void(float)> f;
public:
meaningful_class_name(std::function<void(float)> const& p_f) : f(p_f) {}
};
In fact, if this is the ONLY thing you're using the class for, you might as well just remove it, and use a std::function<void(float)> at the level of the caller.
Advantages of std::function:
1) Less code (1 class for N functions, whereas the virtual method requires N classes for N functions. I'm making the assumption that this function is the only thing that's going to differ between classes).
2) Much more flexibility (You can pass in capturing lambdas that hold state if you want to).
3) If you write the class as a template, you could use it for all kinds of function signatures if needed.
Using std::function solves whatever problem you're attempting to tackle with virtual functions, and it seems to do it better. However, I'm not going to assert that std::function will always be better than a bunch of virtual functions in several classes. Sometimes, these functions have to be private and virtual because their implementation has nothing to do with any outside callers, so flexibility is NOT an advantage.
Disadvantages of std::function:
1) I was about to write that you can't access the private members of the generic class, but then I realized that you can modify the std::function in the class itself with a capturing lambda that holds this. Given the way you outlined the class however, this shouldn't be a problem since it seems to be oblivious to any sort of internal state.
What would be the advantages and drawbacks of these two approaches, and are there other (better ?) ways to do the same thing ?
The issue I can see is "how do you want your class defined?" (as in, what is the public interface?)
Consider creating an API like this:
class Generic
{
// all other members and attributes
explicit Generic(std::function<float(float)> specialFunc);
};
Now, you can create any instance of Generic, without care. If you have no idea what you will place in specialFunc, this is the best alternative ("you have no idea" means that clients of your code may decide in one month to place a function from another library there, an identical function ("receive x, return x"), accessing some database for the value, passing a stateful functor into your function, or whatever else).
Also, if the specialFunc can change for an existing instance (i.e. create instance with specialFunc, use it, change specialFunc, use it again, etc) you should use this variant.
This variant may be imposed on your code base by other constraints. (for example, if want to avoid making Generic virtual, or if you need it to be final for other reasons).
If (on the other hand) your specialFunc can only be a choice from a limited number of implementations, and client code cannot decide later they want something else - i.e. you only have identical function and doubling the value - like in your example - then you should rely on specializations, like in the code in your question.
TLDR: Decide based on the usage scenarios of your class.
Edit: regarding beter (or at least alternative) ways to do this ... You could inject the specialFunc in your class on an "per needed" basis:
That is, instead of this:
class Generic
{
public:
Generic(std::function<float(float> f) : specialFunc{f} {}
void fancy_computation2() { 2 * specialFunc(2.); }
void fancy_computation4() { 4 * specialFunc(4.); }
private:
std::function<float(float> specialFunc;
};
You could write this:
class Generic
{
public:
Generic() {}
void fancy_computation2(std::function<float(float> f) { 2 * f(2.); }
void fancy_computation4(std::function<float(float> f) { 4 * f(4.); }
private:
};
This offers you more flexibility (you can use different special functions with single instance), at the cost of more complicated client code. This may also be a level of flexibility that you do not want (too much).
I have a class:
class A
{
private:
ComplexClass member1;
public:
getMember1(){return member1;};
};
and I have an implementation that, for code simplification (more easily understandable), needs to retrieve that member1 to work with it. The first thing that would come to my mind would be:
ComplexClass *myComplexClass = &getMember1();
myComplexClass.getSomething();
myComplexClass.getSomethingElse();
etc.
which is obviously not correct since I'm retrieving a pointer from a new object and not from member1 (and gets a compiler warning).
My question is: what is the best design to do things like this? How do I keep encapsulation and yet facilitate the access of a members using a pointer to it? (I only want to read from member1, not to write on it).
Should I make a
ComplexClass *getPointerToMember1()
inside the class A?
A const reference will keep them from editing. In my opinion, it makes your intention clearer than a const pointer.
class A
{
private:
ComplexClass member1;
public:
const ComplexClass &getMember1(){return member1;};
};
You're returning the member by value which makes a copy of the ComplexClass member. Thus you aren't working on the actual member when you call the subsequent methods (and what the compiler is telling you).
I think the more idiomatic C++ approach that helps maintain encapsulation and reduces coupling is to create an algorithmic member:
A::doStuff()
{
member1.getSomething();
member1.getSomethignElse();
}
This way anyone that uses class A doesn't care that the implementation uses a ComplexClass but instead just knows that they can tell A to do some work and it will get done in the best possible way.
EDIT for comment: In that case, I would suggest creating methods in A that get the values from ComplexClass (again to hide your implementation). If that's not suitable, then you could return the implementation by const reference: const ComplexClass& getMember1() const { return member1; }
I'm building an hierarchy of objects that wrap primitive types, e.g integers, booleans, floats etc, as well as container types like vectors, maps and sets. I'm trying to (be able to) build an arbitrary hierarchy of objects, and be able to set/get their values with ease. This hierarchy will be passed to another class (not mentioned here) and an interface will be created from this representation. This is the purpose of this hierarchy, to be able to create a GUI representation from these objects.To be more precise, i have something like this:
class ValObject
{
public:
virtual ~ValObject() {}
};
class Int : public ValObject
{
public:
Int(int v) : val(v) {}
void set_int(int v) { val = v);
int get_int() const { return val; }
private:
int val;
};
// other classes for floats, booleans, strings, etc
// ...
class Map : public ValObject {}
{
public:
void set_val_for_key(const string& key, ValObject* val);
ValObject* val_for_key(const string& key);
private:
map<string, ValObject*> keyvals;
};
// classes for other containers (vector and set) ...
The client, should be able to create and arbitrary hierarchy of objects, set and get their values with ease, and I, as a junior programmer, should learn how to correctly create the classes for something like this.
The main problem I'm facing is how to set/get the values through a pointer to the base class ValObject. At first, i thought i could just create lots of functions in the base class, like set_int, get_int, set_string, get_string, set_value_for_key, get_value_for_key, etc, and make them work only for the correct types. But then, i would have lots of cases where functions do nothing and just pollute my interface. My second thought was to create various proxy objects for setting and getting the various values, e.g
class ValObject
{
public:
virtual ~ValObject() {}
virtual IntProxy* create_int_proxy(); // <-- my proxy
};
class Int : public ValObject
{
public:
Int (int v) : val(v) {}
IntProxy* create_int_proxy() { return new IntProxy(&val); }
private:
int val;
};
class String : public ValObject
{
public:
String(const string& s) : val(s) {}
IntProxy* create_int_proxy() { return 0; }
private:
string val;
};
The client could then use this proxy to set and get the values of an Int through an ValObject:
ValObject *val = ... // some object
IntProxy *ipr = val->create_int_proxy();
assert(ipr); // we know that val is an Int (somehow)
ipr->set_val(17);
But with this design, i still have too many classes to declare and implement in the various subclasses. Is this the correct way to go ? Are there any alternatives ?
Thank you.
Take a look at boost::any and boost::variant for existing solutions. The closest to what you propose is boost::any, and the code is simple enough to read and understand even if you want to build your own solution for learning purposes --if you need the code, don't reinvent the wheel, use boost::any.
One of the beauties of C++ is that these kinds of intrusive solutions often aren't necessary, yet unfortunately we still see similar ones being implemented today. This is probably due to the prevalence of Java, .NET, and QT which follows these kinds of models where we have a general object base class which is inherited by almost everything.
By intrusive, what's meant is that the types being used have to be modified to work with the aggregate system (inheriting from a base object in this case). One of the problems with intrusive solutions (though sometimes appropriate) is that they require coupling these types with the system used to aggregate them: the types become dependent on the system. For PODs it is impossible to use intrusive solutions directly as we cannot change the interface of an int, e.g.: a wrapper becomes necessary. This is also true of types outside your control like the standard C++ library or boost. The result is that you end up spending a lot of time and effort manually creating wrappers to all kinds of things when such wrappers could have been easily generated in C++. It can also be very pessimistic on your code if the intrusive solution is uniformly applied even in cases where unnecessary and incurs a runtime/memory overhead.
With C++, a plethora of non-intrusive solutions are available at your fingertips, but this is especially true when we know that we can combine static polymorphism using templates with dynamic polymorphism using virtual functions. Basically we can generate these base object-derived wrappers with virtual functions on the fly only for the cases in which this solution is needed without pessimizing the cases where this isn't necessary.
As already suggested, boost::any is a great model for what you want to achieve. If you can use it directly, you should use it. If you can't (ex: if you are providing an SDK and cannot depend on third parties to have matching versions of boost), then look at the solution as a working example.
The basic idea of boost::any is to do something similar to what you are doing, only these wrappers are generated at compile-time. If you want to store an int in boost::any, the class will generate an int wrapper class which inherits from a base object that provides the virtual interface required to make any work at runtime.
The main problem I'm facing is how to
set/get the values through a pointer
to the base class ValObject. At first,
i thought i could just create lots of
functions in the base class, like
set_int, get_int, set_string,
get_string, set_value_for_key,
get_value_for_key, etc, and make them
work only for the correct types. But
then, i would have lots of cases where
functions do nothing and just pollute
my interface.
As you already correctly deduced, this would generally be an inferior design. One tell-tale sign of inheritance being used improperly is when you have a lot of base functions which are not applicable to your subclasses.
Consider the design of I/O streams. We don't have ostreams with functions like output_int, output_float, output_foo, etc. as being directly methods in ostream. Instead, we can overload operator<< to output any data type we want in a non-intrusive fashion. A similar solution can be achieved for your base type. Do you want to associate widgets with custom types (ex: custom property editor)? We can allow that:
shared_ptr<Widget> create_widget(const shared_ptr<int>& val);
shared_ptr<Widget> create_widget(const shared_ptr<float>& val);
shared_ptr<Widget> create_widget(const shared_ptr<Foo>& val);
// etc.
Do you want to serialize these objects? We can use a solution like I/O streams. If you are adapting your own solution like boost::any, it can expect such auxiliary functions to already be there with the type being stored (the virtual functions in the generated wrapper class can call create_widget(T), e.g.
If you cannot be this general, then provide some means of identifying the types being stored (a type ID, e.g.) and handle the getting/setting of various types appropriately in the client code based on this type ID. This way the client can see what's being stored and deal set/get values on it accordingly.
Anyway, it's up to you, but do consider a non-intrusive approach to this as it will generally be less problematic and a whole lot more flexible.
Use dynamic_cast to cast up the hierarchy. You don't need to provide an explicit interface for this - any reasonable C++ programmer can do that. If they can't do that, you could try enumerating the different types and creating an integral constant for each, which you can then provide a virtual function to return, and you can then static_cast up.
Finally, you could consider passing a function object, in double-dispatch style. This has a definite encapsulation advantage.
struct functor {
void operator()(Int& integral) {
...
}
void operator()(Bool& boo) {
...
}
};
template<typename Functor> void PerformOperationByFunctor(Functor func) {
if (Int* ptr = dynamic_cast<Int*>(this)) {
func(*ptr);
}
// Repeat
}
More finally, you should avoid creating types where they've basically been already covered. For example, there's little point providing a 64bit integral type and a 32bit integral type and ... it's just not worth the hassle. Same with double and float.