I want to create a class iterator that can pass over kinds of A (I mean: linked list and an array [INDEXES]).
how can I do it please?
what should I define in the classes of A, B and C?
class Iterator {
A* a;
public:
A* getnext() {}
A* getcontant() {}
};
class A {
public:
iterator* iterator() {}
};
class B : public A {
linkedlist* head; // a linked list of nodes
};
class C : public A {
INDEXES* vec; // vec is an array of objects of INDEXES
};
any help appreciated!
You probably can't. An iterator (or at least most iterators) are specific to a particular collection.
For example, operator++ for a linked-list iterator will probably do something like location = location -> next; while operator++ for something array-like might do something like ++location; instead.
In theory, you could create a meta-iterator (so to speak) that would work with any iterator that provided a specific interface (e.g., at least ++, * and !=). This is roughly congruent to (a small) part of what concepts were supposed to do. There's still discussion of a "concepts lite" that may provide something similar in the future (at least provide the ability to define such an interface, so you'd be able to directly specify what operations were needed by a particular algorithm).
Such a meta-iterator only really gains much if you do something more than that though, such as providing a number of implementations that allow you to adapt algorithms that use one interface to containers that provide various different interfaces (e.g., could allow applying STL algorithms directly to wxWidgets or Qt collections). The latter a fairly uncommon (at least in C++) simply because it's generally easier to just provide decent iterators in the first place.
Related
If I have the following hypothetical class:
namespace System
{
template <class T>
class Container
{
public:
Container() { }
~Container() { }
}
}
If I instantiate two Containers with different T's, say:
Container<int> a;
Container<string> b;
I would like to create vector with pointers to a and b. Since a and b are different types, normally this wouldn't be possible. However, if I did something like:
std::stack<void*> _collection;
void *p = reinterpret_cast<void*>(&a);
void *q = reinterpret_cast<void*>(&b);
_collection.push(a);
_collection.push(b);
Then later on, I can get a and b back from _collection like so:
Container<string> b = *reinterpret_cast<Container<string>*>(_collection.pop());
Container<int> a = *reinterpret_cast<Container<int>*>(_collection.pop());
My question is, is this the best way for storing a collection of unrelated types? Also would this be the preferred way of storing and retrieving the pointers from the vector (the reinterpret cast)? I've looked around and seen that boost has a nicer way of solving this, Boost::Any, but since this is a learning project I am on I would like to do it myself (Also I have been curious to find a good reason to use a reinterpret_cast correctly).
Consider boost::any or boost::variant if you want to store objects of heterogeneous types.
And before deciding which one to use, have a look at the comparison:
Boost.Variant vs. Boost.Any
Hopefully, it will help you to make the correct decision. Choose one, and any of the container from the standard library to store the objects, std::stack<boost::any>, std::stack<boost::variant>, or any other. Don't write your own container.
I repeat don't write your own container. Use containers from the standard library. They're well-tested.
While it is possible to cast to void * and back, the problem is knowing which type you're popping. After all, you give the example:
Container<string> b = *reinterpret_cast<Container<string>*>(_collection.pop());
Container<int> a = *reinterpret_cast<Container<int>*>(_collection.pop());
However, if you were to accidentally do:
Container<int> a = *reinterpret_cast<Container<int>*>(_collection.pop());
Container<string> b = *reinterpret_cast<Container<string>*>(_collection.pop());
Now you've got pointers to the wrong type, and will likely see crashes - or worse.
If you want to do something like this, at least use dynamic_cast to check that you have the right types. With dynamic_cast, you can have C++ check, at runtime (using RTTI), that your cast is safe, as long as the types being casted (both before and after) have a common base type with at least one virtual method.
So, first create a common base type with a virtual destructor:
class ContainerBase {
public:
virtual ~ContainerBase() { }
};
Make your containers derive from it:
template <typename T>
class Container : public ContainerBase {
// ...
}
Now use a std::stack<ContainerBase *>. When you retrieve items from the stack, use dynamic_cast<Container<int> >(stack.pop()) or dynamic_cast<Container<string> >(stack.pop()); if you have the types wrong, these will check, and will return NULL.
That said, heterogeneous containers are almost always the wrong thing to be using; at some level you need to know what's in the container so you can actually use it. What are you actually trying to accomplish by creating a container like this?
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
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.
I'm currently trying to understand the intrinsics of iterators in various languages i.e. the way they are implemented.
For example, there is the following class exposing the list interface.
template<class T>
class List
{
public:
virtual void Insert( int beforeIndex, const T item ) throw( ListException ) =0 ;
virtual void Append( const T item ) =0;
virtual T Get( int position ) const throw( ListException ) =0;
virtual int GetLength() const =0;
virtual void Remove( int position ) throw( ListException ) =0;
virtual ~List() =0 {};
};
According to GoF, the best way to implement an iterator that can support different kinds of traversal is to create the base Iterator class (friend of List) with protected methods that can access List's members. The concrete implementations of Iterator will handle the job in different ways and access List's private and protected data through the base interface.
From here forth things are getting confusing. Say, I have class LinkedList and ArrayList, both derived from List, and there are also corresponding iterators, each of the classes returns. How can I implement LinkedListIterator? I'm absolutely out of ideas. And what kind of data can the base iterator class retrieve from the List (which is a mere interface, while the implementations of all the derived classes differ significantly) ?
STL doesn't really employ abstract base classes and virtual functions. Instead it is knowingly designed not to be OO (in the sense of GoF) and built entirely on templates, aiming for "compile-time polymorphism". Templates don't care about abstract interfaces. Things work as long as they have a sufficiently similar interface (e.g if you were to call Append push_back instead, more code expecting STL compliant containers would work for you, such as std::back_insert_iterator).
A STL compliant iterator would have to overload lots of operators to behave like a pointer (as far as possible, given the limitations of the container), including *, ->, ++, -- (if bidirectional - doubly linked), == and !=.
The C++ standard library does not use polymorphism and inheritance in its implementation of iterators; instead, it uses C++ template metaprogramming and the notion (but not formal syntax*) of "concepts".
Essentially, it will work if the interface for your iterator class adheres to some set of requirements. This set of requirements is called a "concept". There are several different iterator concepts (see this page for a list of all of them), and they are hierarchical. The basics of creating a compatible C++ iterator is to make your interface conform to the concept. For a simple iterator that goes only in the forward direction, this would require:
A typedef value_type for the value that results from dereferencing your iterator.
A typedef reference_type, which is the reference type for the corresponding value type.
A typedef pointer, which is a pointer type for the corresponding value type.
A typedef iterator_category, which needs to be one of input_iterator_tag, forward_iterator_tag, bidirectional_iterator_tag, or random_access_iterator_tag, depending on your traversal mechanism.
A typedef difference_type indicating the result of subtracting two different iterators.
A const value_type& operator*()const function for dereferencing the iterator.
A value_type& operator*() function if your iterator can be used to manipulate the value.
Increment (operator++() and operator++(int) functions) for seeking forward.
A difference function: difference_type operator-(const type_of_iterator&)
If you choose one of the more advanced iterator categories, you may also need to specify a decrement and plus operator in order to be able to seek backwards or to seek an arbitrary distance.
*The C++ standard library uses concepts so frequently in an informal way, that the C++ standards commitee sought to introduce a formal mechanism of declaring them in C++ (currently they exist only in documentation of the standard library, and not in any explicit code). However, persistent disagreements on the proposal led to it being scrapped for C++0x, although it will likely be reconsidered for the standard after that.
I am trying to find a generic way of accessing a set of containers. I have a standard vector and list in addition to another custom list.
The custom list defines an iterator;
class Iterator: public std::iterator<std::forward_iterator_tag, T> {
// ...
}
Iterator begin() {
return (Iterator(root));
}
Iterator end() {
return (Iterator(NULL));
}
with the appropriate operators overloaded.
Ideally, I would like to do this;
class Foo {
public:
Foo() {
std::list<int> x;
std::vector<int> y;
custom_list<int> z;
iter = x.begin(); // OR
iter = y.begin(); // OR
iter = z.begin();
// ...
};
private:
std::iterator<int> iter;
};
But obviously these are all iterators of different types. I can assume all the containers are of the same type however.
Is there an elegant way to solve this problem?
Here are some articles you might find of interest
Giving STL Iterators a Base Class
Type Erasure for C++ Iterators
any_iterator Class Reference
Better late than never...
The latest issue of C-Vu turned up and guess what was in it: That's right, iterators that do exactly what you wanted.
Unfortunately you need to become a member of the ACCU to view the magazine (the article references the Overload article from 2000 that David links to). But for a measly price a year you get a nice magazine to read, conferences and user groups. When you become a member you can view PDF's of the back issues so what are you waiting for?
A case of being careful what you ask for. The any_iterator classes you see work on an unbounded set of iterator types. You only have three, which you know up front. Sure, you might need to add a fourth type in the future, but so what if that takes O(1) extra lines of code ?
The big advantage of a closed set of possible contained types is that you have an upper bound on sizeof(), which means you can avoid the heap and the indirection it brings. Basically, stuff them all in a boost::variant and call apply_visitor.