473,548 Members | 2,578 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Iterator returning a reference to object of an abstract class?

I have an Element class which is abstract and I would like to have an
object of the Iterator class to iterate over a range of elements.

I would like to use std::for_each to instrument the iteration, which
forces me to have certain interface on the Iterator class.

struct Element {
virtual ~Element() = 0;
};

struct Iterator {
bool operator!=(Iter ator const& ) const;
Iterator& operator++();

// The returned value of this function is the motivation of my
post
// Please, see the comments below the code.
Element& operator*() const;
};

struct Range {
Iterator begin() const;
Iterator end() const;
};
and the client code:

void action(Element const& );
void main()
{
Range range;
std::for_each(r ange.begin(), range.end(), action);
}
Now, after reading some earlier posts, I get the impression that
experience dictates that iterators should return objects by value. In
my case, however, the Element class is abstract, and therefore I
cannot return an object of that class by value.

I must also point out that in this case, so far clients are not
interested in holding references to values returned by the iterator
beyond the next call to operator*. They simply want to use the objects
and forget about them prior to getting the next object from the
iterator.

Thus, I see no need to return pointers (smart pointers, or what have
you) to objects allocated in the heap. Having said that however, I
should expect that, in the future, new clients may require to hold
references to objects beyond the next call to the operator* on the
iterator. In anticipation of that need, I would like to come up with a
design that, while it does not add lots of unnecessary complexity,
will effortlessly accommodate that future need.

Any comments?

Feb 7 '07 #1
3 2791
Belebele wrote:
I have an Element class which is abstract and I would like to have an
object of the Iterator class to iterate over a range of elements.

I would like to use std::for_each to instrument the iteration, which
forces me to have certain interface on the Iterator class.

struct Element {
virtual ~Element() = 0;
};

struct Iterator {
bool operator!=(Iter ator const& ) const;
Iterator& operator++();

// The returned value of this function is the motivation of my
post
// Please, see the comments below the code.
Element& operator*() const;
};

struct Range {
Iterator begin() const;
Iterator end() const;
};
and the client code:

void action(Element const& );
void main()
int main()
{
Range range;
std::for_each(r ange.begin(), range.end(), action);
}
Now, after reading some earlier posts, I get the impression that
experience dictates that iterators should return objects by value.
Oh, what nonsense! Now you're falling into another extreme. First,
your iterator owned the object and returned a reference to it upon
request, but then the reference would become invalid as soon as the
iterator moves onto the next object (which prompted me to suggest
retuning an object instead). Now, the object is actually owned by
the "Range", and there is no concern about the validity of the
reference returned by the iterator. So, return a reference. It's
going to be valid as long as the Range where the object lives keeps
it valid. IOW, disconnect the object and the iterator. Only have
the connection between the iterator and the container it traverses.
[..]

Any comments?
If your "Iterator" is specific to your "Range", you should make
the Iterator class a nested class in Range, most likely. Thus
a semantic relation will be established and the design intent will
be very clear.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Feb 7 '07 #2
Belebele a écrit :
I have an Element class which is abstract and I would like to have an
object of the Iterator class to iterate over a range of elements.

I would like to use std::for_each to instrument the iteration, which
forces me to have certain interface on the Iterator class.

struct Element {
virtual ~Element() = 0;
};
How do you handle affectation with operator=() or copy construtor?
Each subclass should define a Derived::operat or=(const Element& );
Which limit the usage of Element or do you have a specific interface you
did not mentionned here (like some protected deep copy operator) ?

This kind of case never happen in the STL because you cannot define a
container of pure abstract class (unless by pointer).
>
struct Iterator {
bool operator!=(Iter ator const& ) const;
Iterator& operator++();

// The returned value of this function is the motivation of my
post
// Please, see the comments below the code.
Element& operator*() const;
};
If you want to create a STL iterator, you must define traits for your
iterator (google for it and you will find models).
>
struct Range {
Iterator begin() const;
Iterator end() const;
};
and the client code:

void action(Element const& );
void main()
{
Range range;
std::for_each(r ange.begin(), range.end(), action);
}
[snip: answered by Victor Bazarov]

I must also point out that in this case, so far clients are not
interested in holding references to values returned by the iterator
beyond the next call to operator*. They simply want to use the objects
and forget about them prior to getting the next object from the
iterator.
If you are only interested in the for_each algorithm with begin() and
end() as parameter, you would better create a member function
template<typena me Functor>Range:: for_each(Functo r& f) that iterate the
functor on all elements. That would save you the cost of defining an
iterator and make Array a container.
[snip: idem]
Any comments?
Michael


Feb 7 '07 #3
On Feb 7, 5:24 pm, Michael DOUBEZ <michael.dou... @free.frwrote:
Belebele a écrit :
I have an Element class which is abstract and I would like to have an
object of the Iterator class to iterate over a range of elements.
struct Element {
virtual ~Element() = 0;
};

How do you handle affectation with operator=() or copy construtor?
Each subclass should define a Derived::operat or=(const Element& );
Which limit the usage of Element or do you have a specific interface you
did not mentionned here (like some protected deep copy operator) ?
So far, I have not had a need for neither shallow- nor deep-copy
semantics, so yes, I hide both the copy constructor and the operator=.
If you are only interested in the for_each algorithm with begin() and
end() as parameter, you would better create a member function
template<typena me Functor>Range:: for_each(Functo r& f) that iterate the
functor on all elements. That would save you the cost of defining an
iterator and make Array a container.
Even though I have only seen the need to traverse the entire sequence,
I am pretty sure I will be using other algorithms pretty soon.

Feb 7 '07 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

38
3638
by: Grant Edwards | last post by:
In an interview at http://acmqueue.com/modules.php?name=Content&pa=showpage&pid=273 Alan Kay said something I really liked, and I think it applies equally well to Python as well as the languages mentioned: I characterized one way of looking at languages in this way: a lot of them are either the agglutination of features or they're a...
0
3389
by: sks_cpp | last post by:
I am trying to wrap the map iterator for keys and values. However, I seem to run into problems with the values for const_iterator - it works for all other combinations. Below I list my code and the compiler error. Please help if possible. Thanks in advance. // Compiler error ra:/home/ssangapu/personal/C++/STL/mapIter-738>g++ main.cc...
4
2496
by: Scott Smedley | last post by:
Hi all, I'm trying to write a special adaptor iterator for my program. I have *almost* succeeded, though it fails under some circumstances. See the for-loop in main(). Any pointers/help would be muchly appreciated. Apologies for the long post - I couldn't find a shorter way to
14
4862
by: shawnk | last post by:
I searched the net to see if other developers have been looking for a writable iterator in C#. I found much discussion and thus this post. Currently (C# 2) you can not pass ref and out arguments to an iterator method (one returning IEnumerable). I WOULD like to do this for transformative operations on a collection. I realize the need to...
13
4549
by: jois.de.vivre | last post by:
Hi All, I'm trying to write a wrapper class for std::vector to extend some of its functionality. The problem I'm getting into is returning an iterator type from a member function. Here is the essense of what I'm trying to do: //-------code------- #include <vector>
0
2665
by: mailforpr | last post by:
Hi. Let me introduce an iterator to you, the so-called "Abstract Iterator" I developed the other day. I actually have no idea if there's another "Abstract Iterator" out there, as I have never looked for one on the net (I did browse the boost library though). It doesn't matter right now, anyway. To put it simply, Abstract Iterator is...
16
2563
by: mailforpr | last post by:
How do I do that? The thing is, the only information I have about the iterator is the iterator itself. No container it is belonging to or anything. Like template<Iteratorvoid totally_isolated(Iterator& it) { //how do I find out if it points to the end node? }
2
4227
by: =?Utf-8?B?a2VubmV0aEBub3NwYW0ubm9zcGFt?= | last post by:
When creating multiple iterators, the original is defined as returning IEnumerator, ie public IEnumerator GetEnumerator() { yield x; ...} whereas the additional ones are defined as returning IEnumerable, ie public IEnumerable AnotherSortOrder() { yield x;....} Any insights out there as to why the additional iteration methods did not...
1
2760
by: Scott Gifford | last post by:
Hello, I'm working on an providing an iterator interface to a database. The basic thing I'm trying to accomplish is to have my iterator read rows from the database and return constructed objects. My goal here is to abstract away the database part, so that in the future these objects could be constructed from a data source on disk, across...
0
7438
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7707
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7951
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7466
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7803
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6036
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
5082
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3495
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
1
1926
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.