473,394 Members | 1,693 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Polymorphism, iterators and ABCs?

I've run into a situation where the conventional thinking doesn't seem
satisfactory. I have a table of data where each row maps into a struct. I
want to put these into a vector. My overall design uses interfaces for
everything accessed from outside of the namespace. I also have a class
that acts as a wrapper for the structs. For example:

struct Row { long _col0; long _col1; };

class TableRow_IF {
public:
virtual long getCol0() const = 0;
virtual long getCol1() const = 0;
virtual ~TableRow_IF(){}
};

using std::istream;

class TableRow: public TableRow_IF {
bool _foreignEndian;
Row _row;

public:

TableRow(istream& in, istream::pos_type pos, bool foreignEndian_){
/*read the row data*/
}

virtual long getCol0() const {
return _foreignEndian? reendian(_row._col0): _row._col0;
}

virtual long getCol1() const {
return _foreignEndian? reendian(_row._col1): _row._col1;
}

virtual ~TableRow_IF(){}
};
That works. All the user needs to know about is TableRow_IF. But now I
want a collection of rows. I can't make a std::vector<TableRow_IF> because
that would require the instantiation of an abstract class. I can make a
std::vector<TableRow_IF*>, but that is less safe. Even if I use a smart
pointer, I might still inadvertently attempt to dereference a null pointer.
I can create a std::vector<TableRow>, but then I no longer have
polymorphism when I access the elements.

What I want is this:

class Table_IF {
// acts like a std::vector<TableRow_IF>, except it copmiles.
virtual TableInfo() const = 0;// information about the table

};

class Table: public Table_IF {
// derive from std::vector<TableRow> ??????
virtual TableInfo() const { return _info; }
//...
};

Is there a standard C++ pattern for addressing this kind of situation?

This may prove to be the best approach for the entire project:
http://www.research.att.com/~bs/matrix.c

I believe it's what I will try now for the situation described above.

--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Aug 7 '05 #1
5 1284

"Steven T. Hatton" <ch********@germania.sup> wrote in message
news:Tf********************@speakeasy.net...
I've run into a situation where the conventional thinking doesn't seem
satisfactory. I have a table of data where each row maps into a struct. I
want to put these into a vector. My overall design uses interfaces for
everything accessed from outside of the namespace. I also have a class
that acts as a wrapper for the structs. For example:

[SNIP]

What use do you have for a vector of the interface implementations? The only
thing that comes off the top of my head would be that you would probably
want to switch between the implementations and in this case I'd recommend
that you go for a PIMPL idiom. Probably you could elaborate on what you want
to achieve.

Cheers
Chris
Aug 7 '05 #2

"Steven T. Hatton" <ch********@germania.sup> wrote in message
news:Tf********************@speakeasy.net...
I've run into a situation where the conventional thinking doesn't seem
satisfactory. I have a table of data where each row maps into a struct. I
want to put these into a vector. My overall design uses interfaces for
everything accessed from outside of the namespace. I also have a class
that acts as a wrapper for the structs. For example:

struct Row { long _col0; long _col1; };

class TableRow_IF {
public:
virtual long getCol0() const = 0;
virtual long getCol1() const = 0;
virtual ~TableRow_IF(){}
};

using std::istream;

class TableRow: public TableRow_IF {
bool _foreignEndian;
Row _row;

public:

TableRow(istream& in, istream::pos_type pos, bool foreignEndian_){
/*read the row data*/
}

virtual long getCol0() const {
return _foreignEndian? reendian(_row._col0): _row._col0;
}

virtual long getCol1() const {
return _foreignEndian? reendian(_row._col1): _row._col1;
}

virtual ~TableRow_IF(){}
};
That works. All the user needs to know about is TableRow_IF. But now I
want a collection of rows. I can't make a std::vector<TableRow_IF> because that would require the instantiation of an abstract class. I can make a
std::vector<TableRow_IF*>, but that is less safe. Even if I use a smart
pointer, I might still inadvertently attempt to dereference a null pointer. I can create a std::vector<TableRow>, but then I no longer have
polymorphism when I access the elements.

What I want is this:

class Table_IF {
// acts like a std::vector<TableRow_IF>, except it copmiles.
virtual TableInfo() const = 0;// information about the table

};

class Table: public Table_IF {
// derive from std::vector<TableRow> ??????
virtual TableInfo() const { return _info; }
//...
};

Is there a standard C++ pattern for addressing this kind of situation?

This may prove to be the best approach for the entire project:
http://www.research.att.com/~bs/matrix.c

I believe it's what I will try now for the situation described above.

--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand

Russell

If your vector is homogeneous (all elements are of the same type), then just
use that type:

vector<TableRow> table(100);

If your vector is heterogeneous, then vector<Table_IF*> isn't too bad an
idea.

Ben

I don't know if there is a standard practice.
Aug 7 '05 #3
On Sun, 07 Aug 2005 06:57:34 -0400, "Steven T. Hatton"
<ch********@germania.sup> wrote:
I've run into a situation where the conventional thinking doesn't seem
satisfactory.
.... you mean conventional STL-thinking :-)
I have a table of data where each row maps into a struct. I
want to put these into a vector. My overall design uses interfaces for
everything accessed from outside of the namespace. I also have a class
that acts as a wrapper for the structs. For example:

struct Row { long _col0; long _col1; };

class TableRow_IF {
public:
virtual long getCol0() const = 0;
virtual long getCol1() const = 0;
virtual ~TableRow_IF(){}
};

using std::istream;

class TableRow: public TableRow_IF {
bool _foreignEndian;
Row _row; [...]};
That works. All the user needs to know about is TableRow_IF. But now I
want a collection of rows. I can't make a std::vector<TableRow_IF> because
that would require the instantiation of an abstract class.
.... and would slice your derived objects.
I can make a
std::vector<TableRow_IF*>, but that is less safe. Even if I use a smart
pointer, I might still inadvertently attempt to dereference a null pointer.
I can create a std::vector<TableRow>, but then I no longer have
polymorphism when I access the elements.
STL is deliberately designed for values only (a.k.a. 'value
semantics'). It doesn't support OO-programming (polymorphism).
What I want is this:

class Table_IF {
// acts like a std::vector<TableRow_IF>, except it copmiles.
virtual TableInfo() const = 0;// information about the table

};

class Table: public Table_IF {
// derive from std::vector<TableRow> ??????
virtual TableInfo() const { return _info; }
//...
};
Is there a standard C++ pattern for addressing this kind of situation?


What you probably want is a container with 'reference semantics'.
There is no standard STL pattern for that. Many other libraries
provide special containers for pointers. One way is to write your own
STL-compliant container for pointers (to non-copyable entity objects)
with reference semantics. See e.g.

http://www.codeproject.com/vcpp/stl/ptr_vecto.asp

It doesn't completely fulfill all your requirements (e.g. insert of a
NULL is only assert-ed). But, IMO, it's the best STL-compliant
solution you can get WRT reference semantics (but, of course, I'm a
little biased).

Best wishes,
Roland Pibinger
Aug 7 '05 #4
Steven T. Hatton wrote:

[snip]
That works. All the user needs to know about is TableRow_IF. But now I
want a collection of rows. I can't make a std::vector<TableRow_IF>
because
that would require the instantiation of an abstract class. I can make a
std::vector<TableRow_IF*>, but that is less safe. Even if I use a smart
pointer, I might still inadvertently attempt to dereference a null
pointer. I can create a std::vector<TableRow>, but then I no longer have
polymorphism when I access the elements.

[snip]

Waht about using a smart pointer that ensures the validity of the pointee?
Best

Kai-Uwe Bux
Aug 7 '05 #5

Steven T. Hatton wrote:
I've run into a situation where the conventional thinking doesn't seem
satisfactory. I have a table of data where each row maps into a struct. I
want to put these into a vector. My overall design uses interfaces for
everything accessed from outside of the namespace. I also have a class
that acts as a wrapper for the structs. For example:

struct Row { long _col0; long _col1; };

class TableRow_IF {
public:
virtual long getCol0() const = 0;
virtual long getCol1() const = 0;
virtual ~TableRow_IF(){}
};

using std::istream;

class TableRow: public TableRow_IF {
bool _foreignEndian;
Row _row;

public:

TableRow(istream& in, istream::pos_type pos, bool foreignEndian_){
/*read the row data*/
}

virtual long getCol0() const {
return _foreignEndian? reendian(_row._col0): _row._col0;
}

virtual long getCol1() const {
return _foreignEndian? reendian(_row._col1): _row._col1;
}

virtual ~TableRow_IF(){}
};
That works. All the user needs to know about is TableRow_IF. But now I
want a collection of rows. I can't make a std::vector<TableRow_IF> because
that would require the instantiation of an abstract class. I can make a
std::vector<TableRow_IF*>, but that is less safe. Even if I use a smart
pointer, I might still inadvertently attempt to dereference a null pointer.
I can create a std::vector<TableRow>, but then I no longer have
polymorphism when I access the elements.

What I want is this:

class Table_IF {
// acts like a std::vector<TableRow_IF>, except it copmiles.
virtual TableInfo() const = 0;// information about the table

};

class Table: public Table_IF {
// derive from std::vector<TableRow> ??????
virtual TableInfo() const { return _info; }
//...
};

Is there a standard C++ pattern for addressing this kind of situation?

This may prove to be the best approach for the entire project:
http://www.research.att.com/~bs/matrix.c

I believe it's what I will try now for the situation described above.

--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell

Consider using a clone_ptr smart pointer.
Check out the following link:
http://www.codeguru.com/Cpp/Cpp/algo...le.php/c10407/

The clone pointer in the above link works great for a container of
abstract pointers.

Sep 2 '05 #6

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

Similar topics

37
by: Mike Meng | last post by:
hi all, I'm a newbie Python programmer with a C++ brain inside. I have a lightweight framework in which I design a base class and expect user to extend. In other part of the framework, I heavily...
7
by: Mark P | last post by:
I working frequently with similar but distinct geometric objects. For example, a collection of Edge classes. All Edge classes should support certain basic functions, such as getTail(), getTip,...
13
by: Jack | last post by:
I have a class called "Base". This class has a protected member variable "m_base" which can be retrieved using the public member function "GetBaseMember". "m_base" is initialized to "1" and is...
4
by: Paulo Matos | last post by:
Hi all, C++ FAQ Lite points you out to ABCs to define interfaces in C++, however, in a well-defined big system which may consist of a huge number of interfaces, the use of ABCs may incur in a...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
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...
0
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,...
0
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...

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.