what is the best way to put a container class or a some other class inside a class as private or a public member?
Requirements:
1.Vector< someclass> inside my class
2.Add and count of vector is needed interface
If the container's state is part of the class's invariant, then it should, if possible, be private.
For example, if the container represents a three dimensional vector then part of the invariant might be that it always contains exactly 3 numbers. Exposing it as a public member would allow code external to the class to change the containers size, which in turn could cause problems for any routine which requires the container's size to be constant. Keeping the container private limits the places in your software where the container's size can be modified to the class's member functions.
Whether a member is declared Private or Public depends entirely on your application. Could you give some more detail?
One important point to remember when declaring your member is that if you provide a "getter" to retrieve it, then you are no longer encapsulating that object. Instead, it can be good to write wrapper methods exposing only the functionality you wish to expose.
For example, with a Vector member, you might write an AddItem and Clear method, if that's all the functionality you wish to expose.
Since you're talking about a class, I think it should be private. If you want it to be public, rather create a struct - to make it obvious that you want the members variables to be used.
A viable alternative to exposing the vector member is creating a visitor function (or an internal iterator). This way you obey the law of Demeter better:
class ContWrapper {
std::vector<int> _ints;
public:
class Action {
public:
virtual void accept( int i ) = 0;
};
void each_int( Action& a );
};
Also be very careful when exporting e.g. an std::vector<T> from a library, too: the client code might not use the same STL implementation as you did, so the layout of these member variables may differ!
Make all members private and use accessor methods, this allows you to change the implementation later. Only in very unusual circumstances would I make any data member public.
Remember that chaning the implementation happens more often than you may imagine, its not just a case of changing the type of the container but maybe you want to change the mechanism. Say you were storing names in a list, after a while you may chose to index this list with a hash and would like to have the hash updated every time you add a new name. If your implementation is suitably encapsulated doing this is easy, if you have just exposed the vector you would need to make changes that will adjust the interface (and so the change will ripple out).
If this is new to new you have a read of: http://en.wikipedia.org/wiki/Encapsulation_(classes_-_computers)
There is a third way - sometimes it is better to inherit from the container and override it's methods to achieve your goal (for example thread safety). Anyway, making it public almost always isn't a good idea.
Considering that you want to encapsulate the container inside another class implies that it cannot be public, and also the public methods of your class should not expose anything implementation-specific about the container. That way the implementation of your class (i.e. the container) can be changed without changing its interface.
Related
I'm fairly new to c++ templates.
I have a class whose constructor takes two arguments. It's a class that keeps a list of data -- it's actually a list of moves in a chess program.
I need to keep my original class as it's used in other places, but I now need to pass extra arguments to the class, and in doing so have a few extra private data members and specialize only one of the private methods -- everything else will stay the same. I don't think a derived class helps me here, as they aren't going to be similar objects, and also the private methods are called by the constructor and it will call the virtual method of the base class -- not the derived method.
So I guess templates are going to be my answer. Just looking for any hints about how might proceed.
Thanks in advance
Your guess is wrong. Templates are no more the answer for your problem than inheritance is.
As jtbandes said in comment below your question, use composition.
Create another class that contains an instance of your existing class as a member. Forward or delegate operations to that contained object as needed (i.e. a member function in your new class calls member functions of the contained object). Add other members as needed, and operations to work with them.
Write your new code to interact with the new class. When your new code needs to interact with your old code, pass the contained object (or a reference or a pointer to it) as needed.
You might choose to implement the container as a template, but that is an implementation choice, and depends on how you wish to reuse your container.
Templates are used when you want to pass at compile time parameter like values,typenames, or classes. Templates are used when you want to use exactly the same class with the same methods, but applying it to different parameters. The case you described is not this I think.
If they aren't goign to be similar objects you may want to create a specialized class (or collections of function) to use from the various other classes.
Moreover you can think of creating a base class and extending it as needed. Using a virtual private method should allow you to select the method implementation of the object at runtime instead of the method of the base class.
We may help you more if you specify what does they need to share, what does your classes have in common?
The bare bones of my present code looks like this:
class move_list{
public:
move_list(const position& pos, unsigned char ply):pos_(pos),ply_(ply){
//Calculates moves and calls add_moves(ply,target_bitboard,flags) for each move
}
//Some access functions etc...
private:
//private variables
void add_moves(char,Bitboard,movflags);
};
Add_moves places the moves on a vector in no particular order as they are generated. My new class however, is exactly the same except it requires extra data:
move_list(const position& pos, unsigned char ply,trans_table& TT,killers& kill,history& hist):pos_(pos),ply_(ply),TT_(TT),kill_(kill),hist_(hist) {
and the function add_moves needs to be changed to use the extra data to place the moves in order as it receives them. Everything else is the same. I guess I could just write an extra method to sort the list after they have all been generated, but from previous experience, sorting the list as it receives it has been quicker.
I have an obect called an IndexSet, currently defined as a std::vector, that I want to define as a separate type.
I want to be able to interact with it just as though it were a vector, but I also want type protection so that I don't accidentally use a "normal" vector when I want to use an IndexSet.
I have been able to come up with three options for how to do this, none of which please me. I am hoping that there is a fourth that I am missing.
Option #1: typdef
typdef vector<int> IndexSet
This allows me to use an IndexSet exactly as I would a vector, but it gives me zero type protection. I am able to pass a vector into a function expecting an IndexSet with zero complaints.
Option #2: Public Wrapper Class
class IndexSet
{
public:
vector<int> indexes;
};
This will give me type protection, but it requires me to use a level of indirection interacting with it. Instead of saying
set.push_back(1);
I have to say
set.indexes.push_back(1);
Option #3: Private Wrapper Class
class IndexSet
{
public:
push_back....
operator[]...
etc...
private:
vector<int> indexes
};
This will give me both type protection and allow me to interact directly with the IndexSet as though it were a vector, but ONLY if I first create wrapper methods for every single method of std::vector that I want to use with my IndexSet.
Of course, what I'd really like to do is to just create a new class that inherits from vector but has zero implementation of its own, but I know that the standard library containers do not like to be inherited from.
Are there any other options that I'm missing?
Is there some functionality that differs between an IndexSet and a vector? Is there some difference in how these objects are used? If the answer is no, then why do you want to do this?
Your typedef does not suffice only if there is something intrinsically wrong with supplying a std::vector<int> to a functions that expects an IndexSet. That would suggest that an IndexSet does not satisfy an is-a relationship with respect to std::vector<int>. That in turn means that even if you could public inheritance, you shouldn't be doing so.
If the relationship is implemented-by rather than is-a, this suggests using either containment or private (and possibly protected) inheritance. This is much safer than public inheritance from a container class because programmers who use your class have to go out of their way to get a base class pointer. (The way to do it is to use a C-style cast. C-style casts can convert a derived type to a parent class even if the inheritance is not public.)
The advantage of using private inheritance in instead of containment in this case is that you can easily promote selected inherited member functions from private to protected via the using statement. You would have to write a bunch of wrapper functions if you used containment.
class IndexSet : private std::vector<int> {
public:
// Bunch of constructors, elided.
using std::vector<int>::push_back;
using std::vector<int>::operator[];
using std::vector<int>::cherry_picking_of_only_the_stuff_you_want;
};
Update
There are some non-member functions associated with std::vector, specifically comparison operators and std::swap. Making comparable versions for your IndexSet will require wrapper functions, but there aren't that many (six comparison operators plus std::swap), and you only need these if that functionality makes sense for this class.
Let's face it, one solution has all the advantages and just one disadvantage.
If you subclass std::vector, you just have to make sure you don't mix pointers to std::vector and your class, so nobody will delete a pointer to std::vector when it is actually of your subclass.
Whether this is feasible depends on your project. If this is an object that will be used by alot of people, in a public library, an OSS project etc, you might be safer wrapping it, else just subclass std::vector. You'll be fine.
Don't forget to add a comment at your class interface explaining the dangers. And you might be able do disable casting operators for extra safety (make your ctor explicit, ...).
This sounds like a job for....BOOST_STRONG_TYPEDEF. http://www.boost.org/doc/libs/1_54_0/boost/serialization/strong_typedef.hpp
BOOST_STRONG_TYPEDEF(std::vector<int>, IndexSet)
I have about 15~20 member variables which needs to be accessed, I was wondering
if it would be good just to let them be public instead of giving every one of them
get/set functions.
The code would be something like
class A { // a singleton class
public:
static A* get();
B x, y, z;
// ... a lot of other object that should only have one copy
// and doesn't change often
private:
A();
virtual ~A();
static A* a;
};
I have also thought about putting the variables into an array, but I don't
know the best way to do a lookup table, would it be better to put them in an array?
EDIT:
Is there a better way than Singleton class to put them in a collection
The C++ world isn't quite as hung up on "everything must be hidden behind accessors/mutators/whatever-they-decide-to-call-them-todays" as some OO-supporting languages.
With that said, it's a bit hard to say what the best approach is, given your limited description.
If your class is simply a 'bag of data' for some other process, than using a struct instead of a class (the only difference is that all members default to public) can be appropriate.
If the class actually does something, however, you might find it more appropriate to group your get/set routines together by function/aspect or interface.
As I mentioned, it's a bit hard to tell without more information.
EDIT: Singleton classes are not smelly code in and of themselves, but you do need to be a bit careful with them. If a singleton is taking care of preference data or something similar, it only makes sense to make individual accessors for each data element.
If, on the other hand, you're storing generic input data in a singleton, it might be time to rethink the design.
You could place them in a POD structure and provide access to an object of that type :
struct VariablesHolder
{
int a;
float b;
char c[20];
};
class A
{
public:
A() : vh()
{
}
VariablesHolder& Access()
{
return vh;
}
const VariablesHolder& Get() const
{
return vh;
}
private:
VariablesHolder vh;
};
No that wouldn't be good. Image you want to change the way they are accessed in the future. For example remove one member variable and let the get/set functions compute its value.
It really depends on why you want to give access to them, how likely they are to change, how much code uses them, how problematic having to rewrite or recompile that code is, how fast access needs to be, whether you need/want virtual access, what's more convenient and intuitive in the using code etc.. Wanting to give access to so many things may be a sign of poor design, or it may be 100% appropriate. Using get/set functions has much more potential benefit for volatile (unstable / possibly subject to frequent tweaks) low-level code that could be used by a large number of client apps.
Given your edit, an array makes sense if your client is likely to want to access the values in a loop, or a numeric index is inherently meaningful. For example, if they're chronologically ordered data samples, an index sounds good. Summarily, arrays make it easier to provide algorithms to work with any or all of the indices - you have to consider whether that's useful to your clients; if not, try to avoid it as it may make it easier to mistakenly access the wrong values, particularly if say two people branch some code, add an extra value at the end, then try to merge their changes. Sometimes it makes sense to provide arrays and named access, or an enum with meaningful names for indices.
This is a horrible design choice, as it allows any component to modify any of these variables. Furthermore, since access to these variables is done directly, you have no way to impose any invariant on the values, and if suddenly you decide to multithread your program, you won't have a single set of functions that need to be mutex-protected, but rather you will have to go off and find every single use of every single data member and individually lock those usages. In general, one should:
Not use singletons or global variables; they introduce subtle, implicit dependencies between components that allow seemingly independent components to interfere with each other.
Make variables const wherever possible and provide setters only where absolutely required.
Never make variables public (unless you are creating a POD struct, and even then, it is best to create POD structs only as an internal implementation detail and not expose them in the API).
Also, you mentioned that you need to use an array. You can use vector<B> or vector<B*> to create a dynamically-sized array of objects of type B or type B*. Rather than using A::getA() to access your singleton instance; it would be better to have functions that need type A to take a parameter of type const A&. This will make the dependency explicit, and it will also limit which functions can modify the members of that class (pass A* or A& to functions that need to mutate it).
As a convention, if you want a data structure to hold several public fields (plain old data), I would suggest using a struct (and use in tandem with other classes -- builder, flyweight, memento, and other design patterns).
Classes generally mean that you're defining an encapsulated data type, so the OOP rule is to hide data members.
In terms of efficiency, modern compilers optimize away calls to accessors/mutators, so the impact on performance would be non-existent.
In terms of extensibility, methods are definitely a win because derived classes would be able to override these (if virtual). Another benefit is that logic to check/observe/notify data can be added if data is accessed via member functions.
Public members in a base class is generally a difficult to keep track of.
A class having a member function which does not operate on the class's data members ( directly or indirectly), is it decreased encapsulation, tighter coupling, or lower cohesion? Why?
EDIT:
class Data
{
private:
int value_;
public:
Data(int value) : value_(value) {}
int compute(int coef)
{
check(coef);
return coef * value_;
}
void check(int n)
{
if (n < 0 || n > 344) {
throw string("Invalid coef");
}
}
};
The check member functionn verifies the validity of the parameter passed to the compute member function but it has nothing to do with the data members of Data
It is all three. You decrease encapsulation because the function could operate on the class's data members. You give it access to doing so even though it is unnecessary, thereby violating encapsulation. And for much the same reason, it results in lower cohesion and tighter coupling (the class becomes a grouping of functionality that seemingly has little reason to be grouped together.
In C++, free (non-member) functions are generally preferred in cases like this.
I'd say decreased encapsulation, because you give this class a member function which really doesn't belong there. Other two choices are more related to class vs other classes behaviour.
Anyway, I think it's highly debatable.
If a member function does not operate on class's data members then either it should be static or it should not be a member of the class.
In a case like this, you should ask yourself: "Why is this function a member of the class?" If it does something that only makes sense in the context of this particular class, then you make it static or at least const, and maybe even private.
On the other hand, if the function makes sense outside the context of the class, or, worse, if it is used outside the context of the class, then it reduces cohesion and increases coupling. It reduces cohesion, because it does not logically belong to the class of which it is a member. It increases coupling because while it may be used outside the context of its class, that class must nevertheless be known to the caller of the function. In this case, the function should simply not be a member of the class. Then there is no impact on cohesion or coupling.
I don't think it has any impact on encapsulation, though, since it does not expose any class members that are not already exposed.
Edit:
In your particular case check() should be private and either static or const. compute() should be const.
I'll give an example
Let's say you build a class called Angle to haul around angles in different units.
Having a sin() function on the class would be worthless and just bloat the class interface whereas that function should simply be a separate free function.
Read this link on the Interface Principle: http://www.gotw.ca/publications/mill02.htm
That depends. If the method needs access to anything private or protected then it needs to be a member or a friend of the class. That being said, you should always limit as much as possible the number of entities having access to the class' internals, because each entity can introduce bugs. Sometimes you can eliminate a private or protected member, and if that eliminates the original method's need for privileges then you can extract it outside the class.
If a method belongs in the class (something only you can judge) then it should be part of the class' interface. Remember though that being part of the class' interface doesn't imply being a member of the class. What reduces cohesion and encapsulation is not a method being a member but a method having more privileges than it needs. The same holds for increasing coupling and reduced information-hiding.
And yet that being said, there is an interesting debate about the tradeoffs between humane interfaces and minimal interfaces. This relates here, in that you might have a function that serves as a mere inline (alias) call for another function, in making an interface more intuitive. Such a function doesn't need any member access whatsoever but in C++ it's needed for an intuitive call as a member -- should you value intuitive interfaces and be part of the humane interface school of thought.
In your revised question (with the code), the magic numbers in check should be static const int in the class (and check should be a static member).
Another option would be to construct the class with constraints as parameters, and private members. Then check would not be static but again it would need to access class members.
You need to post an example that both exhibits good design and meets your stated limitations. I doubt that can be done. To me, what you have described is a code smell as such a function should always be free.
As all three expressions proposed "decreased encapsulation", "tighter coupling" and "lower cohesion" are a mesure of a program change (there is source before and a source after), it's not possible to answer your question.
Basically I'm saying Tighter coupling than what ? Duh ?
If you are asking about your proposed version and the use of an external function for check instead, I believe others have already answered.
About coupling and Cohesion you may want to read that
Structure's member are public by default ans class's members are private by default. We can access private data members through a proper channel (using member function). If we have access to member functions we can read/write data in private data member, so how it is secure...we are accessing it and we are changing data too.....
Access specifiers, such as private and public have nothing to do with security. In C++, for example, these specifications get compiled away and don't even exist in the compiled binary.
Rather, access specifiers are designed to make types easy to use correctly, and difficult to use incorrectly.
There are only two syntactic differences between class and struct:
In a class, members and base classes are by default private, whereas in a struct, they are public by default.
For historical reasons, class can be used instead of typename to declare a template type parameter.
In fact, there's no difference between
struct X {
void f() {}
private:
int i;
};
and
class Y {
int i;
public:
void f() {}
};
The only way that a class is more "secure" than a struct is that it gently "presses" you towards better encapsulation by defaulting to private members.
There really was no need to introduce a new keyword class, Stroustrup himself said that on a few occasions. (Read his book The Design and Evolution of C++ if you're interested in such things.) Basically, class was introduced to emphasize the fact that a struct with member functions isn't really a "structure" anymore in the way the term was used in C: a collection of loosely coupled objects of built-in types. It's a "class" in the sense the term is used in statically typed object-oriented languages, even though syntactically, it's no real difference from a struct.
primarily because the member functions can validate the values before storing them. eg say you have a field called 'age', which must be between 0 and 150. in a structure (or a class with a public field), you could just do obj.age = 200. whereas if you only had a setAge(int) method, that method could sanity check the value is between 0 and 150 before storing, possibly throwing an exception if necessary or just clamping the value if not.
the public/private/protected keywords are not meant for security but rather for encapsulation. you design your class by separating the implementation (where the private/protected members are used - those actually used to implement the functionality) from the interface (where you expose the public members - which users of the class -other objects- will access/call) and thus you are later able to change the private parts without changing the interface. the outside objects only need to know about the public members and use these safely regardless of the implementation.
if you are speaking about security, think that anyone could change the private members of your class if they really wanted to and knew the internal structure of the class , just by overwriting the appropriate memory locations with new values - but the problem here is not about security, it's at a lower level
Taking that classes and structs are exactly the same besides the default access, the question is how encapsulating the internal representation from the interface helps build more robust code.
The main difference is that you control when and how your class data is modified, and as such you can control your class invariants. Consider a simple vector class that has a pointer and a size. By having them private you can control how they change: if the resize method is called, both the pointer and the internal size variable will be coherently updated, keeping the invariant that accessing any position in the range [0..size) is well defined. If the member attributes were public, user code would update the storage or size without actually updating the other field, and that invariant could be broken.
Many classes have internal invariants for the correct usage. If you write a class that contains a string with user email addresses, by providing an accessor method you can control that the value passed in is a valid email address, while if the email field was public user code could reset it to anything...
The whole thing is that you control how your members are accessed and modified and that reduces the number of places where mistakes can be made and/or your chances of detecting it.