C++ Iterators, interfaces and pointers
I'm trying to use c++ iterators with interfaces, but does not manage to make it working.
I'm a bit lost with what type to choose for the vector contents. Is this need to be a pointer ? do I have to make a "new Implementation()"? In brief, it is unclear to me, and I can't manage to find useful examples about that.
Here are the interfaces and implementations (the .h file).
class Interface{
public:
virtual int method() = 0;
};
class Implementation1 : public Interface{
public:
int method();
};
class Implementation2 : public Interface{
public:
int method();
};
The .cpp file:
#include "content.h"
int Implementation1::method(){
return 1;
}
int Implementation2::method(){
return 2;
}
And my main function:
#include "content.h"
#include <vector>
#include <iostream>
using namespace std;
int main(void)
{
// create the vector and put elements in it
vector<Interface*> elements;
elements.push_back(new Implementation1());
elements.push_back开发者_开发问答(new Implementation1());
elements.push_back(new Implementation2());
// now iterate on them
vector<Interface*>::iterator iterator;
for(iterator = elements.begin(); iterator != elements.end(); ++iterator ){
*iterator->method();
}
return 1;
}
the compilator is outputting:
main.cpp: In function ‘int main()’: main.cpp:19: error: request for member ‘method’ in ‘* iterator.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator-> with _Iterator = Interface**, _Container = std::vector >’, which is of non-class type ‘Interface*’
Any idea about what I'm doing wrong here ?
Change *iterator->method();
to (*iterator)->method();
The former dereferences the return of iterator->method(). Interface* doesn't have a method(), it doesn't have anything.
You want to dereference the iterator to get to your pointer, and then dereference IT.
You've basically got the same thing as Iterator** so act accordingly.
+1 for Noah about the compile error with iterator, that's a good explanation. As for your former question:
I'm a bit lost with what type to choose for the vector contents. Is this need to be a pointer ? do I have to make a "new Implementation()"?
Yes, this has to be a pointer. The reason is simple: the vector of type T stores (and owns) only elements of type T, not subtypes - and there are good reasons for that (what if the subclass had a different size?).
Therefore you have to store the objects somewhere and keep the pointers in the vector. In fact, storing them on the free store via operator new
is the easiest option.
If you want your life a bit easier, you can use boost::ptr_vector
for your purposes.
try (*iterator)->method();
There's nothing inherently invalid about what you've done, but creating a vector of raw pointers is typically a bad idea, you should use an ownership enforcing pointer (a "smart" pointer) like shared_ptr. And you also don't need to de-reference the iterator, it should just offer ->method() directly. However, I don't see anything directly uncompilable with this code, except possibly your *iterator->method()
, cause last time I checked de-reference has a really low precedence and you may be doing *(iterator->method())
which is uncompilable.
精彩评论