S
scg_
What follows is a question by an absolute beginner – you have been warned:
I am using the following class layout, which is inspired by Bruce
Eckel's "Thinking in C++":
template <class T>
class B {
private:
T* data_;
int size_;
public:
int size() const {return size_;}
class iterator;
friend class iterator;
class iterator {
T* p;
public:
iterator(): p(0) {}
iterator(const B<T>& x): p(x.data) {}
T& operator*() {return *p;}
T* operator++(){return ++p;}
};
iterator begin() const {return iterator(*this);}
\\...
};
Furthermore, I define a function operating on B objects,
essential_function(const B &), which relies on the member function
explicitly listed above. Since I recently decided to change the
implementation of some of the details of B, I thought setting up an
abstract base class would be auspicious. In particular, I was hoping to
implement the algorithm in terms of the purely virtual member functions
of the abstract class:
template <class T>
class A {
public:
virtual int size() const = 0;
class iterator;
friend class iterator;
class iterator {
public:
virtual T& operator*() const = 0;
virtual T* operator++() = 0;
};
virtual iterator begin() const = 0; // error
};
class B : public A<T> {
//...
};
Unfortunately, this class A layout does not compile due to covariant
return type issues, i.e. B<T>::iterator B<T>::begin() overrides
A<T>::iterator A<T>::begin().
When I comment the line "virtual iterator begin() const = 0", it
compiles. However, not much is gained, since I can not implement
essential_function(const A &) in terms of the abstract class A:
template <class T>
void essential_function(const A<T>& x) {
typename A<T>::iterator iter;
iter = x.begin();
}
error: cannot declare variable `iter' to be of type `A<T>::iterator'
because virtual functions are abstract ... and A<T> has no has no
member named 'begin'.
Don't get me wrong - I am not particularly surprised about the errors
(now that I spend some time thinking about it).
Still, how can I implement what I (in essence) suggest above?
Thanks
I am using the following class layout, which is inspired by Bruce
Eckel's "Thinking in C++":
template <class T>
class B {
private:
T* data_;
int size_;
public:
int size() const {return size_;}
class iterator;
friend class iterator;
class iterator {
T* p;
public:
iterator(): p(0) {}
iterator(const B<T>& x): p(x.data) {}
T& operator*() {return *p;}
T* operator++(){return ++p;}
};
iterator begin() const {return iterator(*this);}
\\...
};
Furthermore, I define a function operating on B objects,
essential_function(const B &), which relies on the member function
explicitly listed above. Since I recently decided to change the
implementation of some of the details of B, I thought setting up an
abstract base class would be auspicious. In particular, I was hoping to
implement the algorithm in terms of the purely virtual member functions
of the abstract class:
template <class T>
class A {
public:
virtual int size() const = 0;
class iterator;
friend class iterator;
class iterator {
public:
virtual T& operator*() const = 0;
virtual T* operator++() = 0;
};
virtual iterator begin() const = 0; // error
};
class B : public A<T> {
//...
};
Unfortunately, this class A layout does not compile due to covariant
return type issues, i.e. B<T>::iterator B<T>::begin() overrides
A<T>::iterator A<T>::begin().
When I comment the line "virtual iterator begin() const = 0", it
compiles. However, not much is gained, since I can not implement
essential_function(const A &) in terms of the abstract class A:
template <class T>
void essential_function(const A<T>& x) {
typename A<T>::iterator iter;
iter = x.begin();
}
error: cannot declare variable `iter' to be of type `A<T>::iterator'
because virtual functions are abstract ... and A<T> has no has no
member named 'begin'.
Don't get me wrong - I am not particularly surprised about the errors
(now that I spend some time thinking about it).
Still, how can I implement what I (in essence) suggest above?
Thanks