473,385 Members | 1,944 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,385 software developers and data experts.

specialized containment???

Hello, maybe somebody can enlighten me? :)
I wasn't really sure how to concisely describe the following scenario
so it was tricky to search for help.
Simplifying the problem...
I have a home which contains people. I also want a SpecialHome which
has to contain a set of SpecialPersons.
class Home {
Person* getPerson(id);

vector<Person*> m_People;
}

class SpecialHome : public CHome {
SpecialPerson* getPerson(id);
vector<SpecialPerson*> m_People;
}
So obviously the above SpecialHome class isn't how I would want to
implement this. There's nothing being inherited, the list of pointers
are unnecessarily duplicated, etc. The problem is that a number of
Home methods accept and return Persons. In my more complicated
situation, I really want to avoid a templatized Home class (it would
make for quite a confusing class diagram). I guess accepting Persons
isn't such a problem thanks to polymorphism, but returning them is
(I've also got a Person iterator class in an effort to abstract away
the containment mechanism in Home).

The approach I've tried taking is to remove all of these Person-related
methods from Home and put them is a sort of templatized "manipulator"
class. This manipulator was made a friend of Home and SpecialHome so
it more or less can do whatever it pleases. Naturally, there's a lot
of dynamic_casting since the vector lives in the base class (for some
reason dynamic_casting always makes me uncomfortable).

I'm having trouble getting this to compile because of complications
with the more convoluted scenario I'm dealing with.
This lead me to take a step back and ask myself if there isn't a better
way to do design the class structure. I would imagine the scenario I
described above is a fairly common one.

Any tips are greatly appreciated!
cheers!

Nov 22 '05 #1
3 1327
* Mr Dyl:

I have a home which contains people. I also want a SpecialHome which
has to contain a set of SpecialPersons.
class Home {
Person* getPerson(id);

vector<Person*> m_People;
}

class SpecialHome : public CHome {
SpecialPerson* getPerson(id);
vector<SpecialPerson*> m_People;
}


That sketch isn't really enough to go on, because you haven't indicated
access, and for this kind of problem what's private and what's public
and what's const or not is key.

Here's a more fleshed-out sketch that illustrates the fundamental
problem you're up against:

class Person {};
class ShortPerson: public Person {};
class LongPerson: public Person {};

class Home
{
public:
addPerson( Person* );
std::vector<Person const*> persons() const;
};

class ShortPersonHome: public Home
public:
addPerson( ShortPerson* );
std::vector<ShortPerson const*> persons() const;
};

class LongPersonHome: public Home
public:
addPerson( LongPerson* );
std::vector<LongPerson const*> persons() const;
};

int main()
{
ShortPersonHome home;
Home* pHome = &home;
LongPerson longPerson;

pHome->addPerson( &longPerson ); // Oops, roof is too low!
}

As you can see it's a problem of mutability, not of downcasting the
internal representation (although that's also a problem, but managable).

What you need is something like

// Home
// MutableHome
// ShortPersonHome
// MutableShortPersonHome
// LongPersonHome
// MutableLongPersonHome

class Home
{
public:
std::vector<Person const*> persons() const;
};

class MutableHome: public Home
{
public:
addPerson( Person* );
};

class ShortPersonHome: public Home
public:
std::vector<ShortPerson const*> persons() const;
};

class MutableShortPersonHome: public ShortPersonHome
{
public:
addPerson( ShortPerson* );
};

class LongPersonHome: public Home
{
public:
std::vector<LongPerson const*> persons() const;
};

class MutableLongPersonHome: public LongPersonHome
{
public:
addPerson( LongPerson* );
};

Now in ShortPersonHome you can safely assume that any Person in there is
really a ShortPerson, because no other kinds of persons can be added.
So you can simply provide an internal accessor function that downcasts.
As I wrote, that part is a managable problem, also with other solutions:
note that C++ does support covariance for function results.

Hth.,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 22 '05 #2
Hey Alf,
thanks for the reply.
Interesting. At the moment I'd only been thinking about the
relationship between parent and child classes so I hadn't even been
thinking about the problem you pointed out.

A question though,

Home contains (I assume) a list of persons accessed through:

std::vector<Person const*> persons() const

LongPersonHome also provides access to this list (but they are
LongPersons now):

std::vector<LongPerson const*> persons() const;

How are you able to cast a std::vector<Person const*> to
std::vector<LongPerson const*>?
I think maybe there's something fundamental here that I'm not seeing.
Thanks again!
Dylan

Nov 22 '05 #3
* Mr Dyl:

Home contains (I assume) a list of persons accessed through:

std::vector<Person const*> persons() const

LongPersonHome also provides access to this list (but they are
LongPersons now):

std::vector<LongPerson const*> persons() const;

How are you able to cast a std::vector<Person const*> to
std::vector<LongPerson const*>?
Note that the signature of 'persons' specifies a copy.

A mutable collection of T isn't really convertible along with the type
of T. That's a problem with Java arrays, for example, where Java is
reduced to run-time type-checking, throwing an exception if the type of
an element assigned to an array is of the wrong dynamic type,
<url:
http://java.sun.com/docs/books/jls/third_edition/html/arrays.html#10.10>,
which implies a run-time check of every assignment to a Java array.

Note that that this concerns an array casted analogous to casting
std::vector<LongPerson const*> to std::vector<Person const*>, an upcast,
which is opposite and many might think safer than the cast you mention.

So, let 'persons' create a _copy_... ;-)

Or, its return type is non-mutable collection, of a collection type that
supports this kind of thing; that means essentially, a collection type
you have defined.

Or, represent it by a collection of member functions that provide
iteration.

Or, represent it by a general standard-library compatible iterator.

I think maybe there's something fundamental here that I'm not seeing.


Yes, you're now up against the idea of "virtual data".

<url:
http://www.parashift.com/c++-faq-lite/value-vs-ref-semantics.html#faq-31.2>.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 22 '05 #4

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

Similar topics

2
by: Chandrashekara Adiga | last post by:
hi This is particular to Containment classes .. ( just taking an example from rougewave ) Can someone point out How destrutor of new RWDate(2, "Nov", 1980) will be called? Is is our...
0
by: Jim Douglas | last post by:
{System.Collections.Specialized.ListDictionary.NodeKeyValueCollection} : {System.Collections.Specialized.ListDictionary.NodeKeyValueCollection} Count: 25 ?entry.Contains("MachineName") ...
1
by: Dave | last post by:
Hello all, The methodology of policy-based design states that one should inherit from policy classes and, of course, these classes must provide an agreed-upon public interface and semantics. ...
3
by: Ruben Campos | last post by:
I have a template class, and I want to create partially (totally) specialized versions of it, by adding new methods to the original base template specification. But it seems that partially...
1
by: Baski | last post by:
Does anyone knows any article explains effective use of containment and aggregation with interfaces using C#. Thanks Baski
4
by: Kerr | last post by:
Hi all, I've been scouring the internet for help with this problem and every occurance i've seen reconstructs the problem but no one seems to have a solution. Hoping that you guys can help me. ...
0
by: David Veeneman | last post by:
This post is for the Google crawler-- no response in required. Can a containment hierarchy made up of two collections derived from BindingList<T> be data-bound to master-detail dataGridView...
0
by: passion | last post by:
"Specialized Search Engines" along with Google Search Capability (2 in 1): http://specialized-search-engines.blogspot.com/ Billions of websites are available on the web and plenty of extremely...
12
by: Daz | last post by:
Hi guys, I'm trying to make a script.aculo.us sortable list have a limited number of elements in it. Now I can check for this really easily and have a warning message, and of course the php...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
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...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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
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
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...

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.