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

STL list related

Hi,

why cant a list<derived*be implicitly castable to list<base*>?

Any alternatives other than global operators?

thanks in advance,
Naren.

Nov 8 '06 #1
9 1587
Hi Naren,

Firstly list<base*is different from list<derived*>, there is no
inheritance which is linking these.

If you want to use both derived class and base class pointer in a
common list, then in that case you can consider keeping derived* in
list<base*container.

To make it more clear, consider the following example.

list<derived*dList;
list<base*>& refBList = dList; //ERROR. Let's assume this would work
for now
refBList.push_back(new base());
//Now dList containes a pointer to base*...PROBLEM

Regards
- Amit Gupta

Naren wrote:
Hi,

why cant a list<derived*be implicitly castable to list<base*>?

Any alternatives other than global operators?

thanks in advance,
Naren.
Nov 8 '06 #2


On Nov 8, 8:52 am, "Naren" <narendranath.thad...@gmail.comwrote:
why cant a list<derived*be implicitly castable to list<base*>?
list<derived*doesn't inherit from list<base*>

What is it that you trying to accomplish?
Any alternatives other than global operators?
How would a global operator accomplish what you are trying to do?

Nov 8 '06 #3

Naren wrote:
Hi,

why cant a list<derived*be implicitly castable to list<base*>?
http://www.parashift.com/c++-faq-lit....html#faq-21.3

Gavin Deane

Nov 8 '06 #4


Gavin Deane wrote:
Naren wrote:
>>Hi,

why cant a list<derived*be implicitly castable to list<base*>?


http://www.parashift.com/c++-faq-lit....html#faq-21.3
I'm not following here. The containers are of pointers, not objects. (I
assume the objects are created on the heap.)

How would this be wrong?:

struct F
{
long value;
virtual ~F( ) { }
};

struct E : public F
{
long value2;
virtual ~E( ) { }
};

main(...)
{
std::vector<E*eVect;
eVect.push_back( new E );
eVect.front( )->value2= 10;

std::vector<F*fVect;
fVect.push_back( eVect.front( ) );

std::cout << dynamic_cast<E*>( fVect.front( ) )->value2 << '\n';
}
Gavin Deane
It works.
Thanks, Dan.

Nov 8 '06 #5

Dan Bloomquist wrote:
Gavin Deane wrote:
Naren wrote:
>Hi,

why cant a list<derived*be implicitly castable to list<base*>?

http://www.parashift.com/c++-faq-lit....html#faq-21.3

I'm not following here. The containers are of pointers, not objects. (I
assume the objects are created on the heap.)
The containers have to be of pointers not objects otherwise there is no
polymorphism involved at all and the question can't even arise.
How would this be wrong?:
<snip code that contains a dynamic cast from base* to derived*>
Your example is not what the OP, or the FAQ I pointed to, is talking
about.

The OP wants to be able to convert implicitly from a list<derived*to
a list<base*>. The point in the FAQ is that, if Fruit is the base class
and Apple and Orange are two classes derived from Fruit, converting a
container of Apples to a container of Fruit would allow you to put an
Orange in the container of Apples. Implicit in that is that the
containers hold pointers, not objects. It is only possible to have the
concept of a container of Fruit holding Apples if the stored type is a
pointer. The OP's question was about containers of pointers.

#include <list>
using std::list;

class base { /* ... */ };

class derived1 : public base { /* ... */ };

class derived2 : public base { /* ... */ };

void f(list<base*>& bl)
{
// This is OK. derived1 and derived2 both derive
// from base so both can be pointed to by a base*
bl.push_back(new derived1);
bl.push_back(new derived2);
}

int main()
{
list<base*base_list;
f(base_list);
// base_list now contains two pointers. The first
// points to a derived1, the second points to a
// derived2.

// The first push_back is OK
// The second won't compile because d1_list
// is a list of derived1* not a list of derived2*
list<derived1*d1_list;
d1_list.push_back(new derived1);
d1_list.push_back(new derived2);

list<derived1*another_d1_list;
// The OP wants to be able to do this somehow
f(another_d1_list);
// If the above were possible, what should happen
// when function f tries to put a derived2* in
// this list of derived1*? That would be
// equivalent to the statement above that quite
// sensibly does not compile.
}

Also have a look at the rest of FAQ 21.

Gavin Deane

Nov 9 '06 #6


Gavin Deane wrote:
>
<snip code that contains a dynamic cast from base* to derived*>
Your example is not what the OP, or the FAQ I pointed to, is talking
about.

The OP wants to be able to convert implicitly from a list<derived*to
a list<base*>. The point in the FAQ is that, if Fruit is the base class
and Apple and Orange are two classes derived from Fruit, converting a
container of Apples to a container of Fruit would allow you to put an
Orange in the container of Apples. Implicit in that is that the
containers hold pointers, not objects. It is only possible to have the
concept of a container of Fruit holding Apples if the stored type is a
pointer. The OP's question was about containers of pointers.
Hi Gavin,
Thanks for the time. I am really trying to understand what I'm missing.
>
#include <list>
using std::list;

class base { /* ... */ };

class derived1 : public base { /* ... */ };

class derived2 : public base { /* ... */ };

void f(list<base*>& bl)
{
// This is OK. derived1 and derived2 both derive
// from base so both can be pointed to by a base*
bl.push_back(new derived1);
bl.push_back(new derived2);
}
Good! I've done that several times so as to keep an assortment of objects.
int main()
{
list<base*base_list;
f(base_list);
// base_list now contains two pointers. The first
// points to a derived1, the second points to a
// derived2.

// The first push_back is OK
// The second won't compile because d1_list
// is a list of derived1* not a list of derived2*
list<derived1*d1_list;
d1_list.push_back(new derived1);
d1_list.push_back(new derived2);
Yes.
>
list<derived1*another_d1_list;
// The OP wants to be able to do this somehow
f(another_d1_list);
// If the above were possible, what should happen
// when function f tries to put a derived2* in
// this list of derived1*? That would be
// equivalent to the statement above that quite
// sensibly does not compile.
Ok, the op wrote:
why cant a list<derived*be implicitly castable to list<base*>?
And I've reread the faq. Now I get it.

I would have never thought of doing it and misunderstood, I guess that's
a good thing. To be sure, he wants to treat the derived* like a base*,
not just grab the derived by the base.
Gavin Deane
Thanks, Dan.

Nov 10 '06 #7
Dan Bloomquist wrote:
Gavin Deane wrote:

<snip code that contains a dynamic cast from base* to derived*>
Your example is not what the OP, or the FAQ I pointed to, is talking
about.

The OP wants to be able to convert implicitly from a list<derived*to
a list<base*>. The point in the FAQ is that, if Fruit is the base class
and Apple and Orange are two classes derived from Fruit, converting a
container of Apples to a container of Fruit would allow you to put an
Orange in the container of Apples. Implicit in that is that the
containers hold pointers, not objects. It is only possible to have the
concept of a container of Fruit holding Apples if the stored type is a
pointer. The OP's question was about containers of pointers.

Hi Gavin,
Thanks for the time. I am really trying to understand what I'm missing.

#include <list>
using std::list;

class base { /* ... */ };

class derived1 : public base { /* ... */ };

class derived2 : public base { /* ... */ };

void f(list<base*>& bl)
{
// This is OK. derived1 and derived2 both derive
// from base so both can be pointed to by a base*
bl.push_back(new derived1);
bl.push_back(new derived2);
}

Good! I've done that several times so as to keep an assortment of objects.
int main()
{
list<base*base_list;
f(base_list);
// base_list now contains two pointers. The first
// points to a derived1, the second points to a
// derived2.

// The first push_back is OK
// The second won't compile because d1_list
// is a list of derived1* not a list of derived2*
list<derived1*d1_list;
d1_list.push_back(new derived1);
d1_list.push_back(new derived2);

Yes.

list<derived1*another_d1_list;
// The OP wants to be able to do this somehow
f(another_d1_list);
// If the above were possible, what should happen
// when function f tries to put a derived2* in
// this list of derived1*? That would be
// equivalent to the statement above that quite
// sensibly does not compile.

Ok, the op wrote:
why cant a list<derived*be implicitly castable to list<base*>?
And I've reread the faq. Now I get it.

I would have never thought of doing it and misunderstood, I guess that's
a good thing. To be sure, he wants to treat the derived* like a base*,
not just grab the derived by the base.
Gavin Deane

Thanks, Dan.
Thanks EveryBody.

I do undrstand that we cannot do for the same reason which you guys
have mentioned.
but just wanted to know if you guys have encountered it in design.
Let's say an Entity A "has a relationship" with a group of Entity C.
Entity C "is a" Entity B.
Entity D requires to work on a group of constant Entity B(D does not
change group of Bs)
Now from "A" "D" can only get a group of C, but logically they could
have been treated as group of Bs. So I just wanted to know if there is
any better method rather than tweking A and making it hold a group of
Bs.

In C++ terms
class B
{};
class A
{
list<C*x;
};
class C: public B
{
};
class D
{
func(const list<B*>& a);
};

int main()
{
A p;
D k;
k.func(p.GetList());
}

To make it work change A to
class A
{
list<B*x;
};

Though logically A does not really hold items of type B and func does
not change the list.

Thanks in advance.

Rgds,
Naren.

Nov 13 '06 #8
Naren schreef:
Hi,

why cant a list<derived*be implicitly castable to list<base*>?
Because the first cannot contain AnotherDerived*, and the second can.

Now, consider this function:
void foo(list<base*>& BaseList) {
static AnotherDerived object;
BaseList.push_back(&object);
}

HTH,
Michiel Salters

Nov 13 '06 #9


Naren wrote:
>
In C++ terms
class B
{};
class A
{
list<C*x;
};
class C: public B
{
};
class D
{
func(const list<B*>& a);
};

int main()
{
A p;
D k;
k.func(p.GetList());
}

To make it work change A to
class A
{
list<B*x;
};

Though logically A does not really hold items of type B and func does
not change the list.
Here I would say, 'But it does'. And considering the design of a more
complete program, where would these 'C' objects have come from? Where
would they be fundamentally stored? Why did you derive 'C' from 'B'?

When it comes time to destroy these objects they should all be kept in
some general 'B' container or you could have an object management nightmare.

I don't see how in the real world it should not be necessary to keep a
container of 'C'. A container of 'B' that is known to be 'C' might make
more sense. How about:

struct A
{
virtual ~A( ) { }
};

struct B : A
{
};

struct VB : std::vector<A*>
{
B* operator [ ] ( int i )
{
assert( dynamic_cast<B*>( at( i ) ) );
return dynamic_cast<B*>( at( i ) );
//or return a null if not castable
}
};

and then you can:
VB vb;
B* b= vb[i];
or:
A* a= vb[i];

Best, Dan.

Nov 13 '06 #10

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

Similar topics

5
by: Kenneth | last post by:
<list> seems to be a powerful structure to store the related nodes in memory for fast operations, but the examples I found are all related to primitive type storage. I'm doing a project on C++...
5
by: chris vettese | last post by:
I have a table called table1 that has a one to many relationship to table2. What I would like to do is have a form with two list boxes on it. The first list box will have a field from all of the...
1
by: Colm O'Hagan | last post by:
Hi there, I wonder if anyone out there can help me. I'm setting up a database at the moment for a manufacturing company. In my database I have a table listing all the company products; I have...
1
by: John M | last post by:
I have 1st list box from table Grain 2nd list box from related table Varieties, related by GrainID At the moment Grain listbox is on its own form and Variety listbox is on subform in Grain form....
6
by: Joe | last post by:
I have 2 multi-list boxes, 1 displays course categories based on a table called CATEGORIES. This table has 2 fields CATEGORY_ID, CATEGORY_NAME The other multi-list box displays courses based on...
7
by: Kieran Simkin | last post by:
Hi all, I'm having some trouble with a linked list function and was wondering if anyone could shed any light on it. Basically I have a singly-linked list which stores pid numbers of a process's...
1
by: David | last post by:
Hi, I have a field which holds the Product IDs of related products in a format of: 1#5#4#7 Where the numbers are the Related Product IDs. I am trying to create a form to manage this info.
6
by: Jonathan | last post by:
Hi. I'm having trouble figuring out what I should be doing here. I'm trying to remove an object from a list. The function is: void Alive::FromRoom () { list<Alive>::iterator iter =...
0
by: kirby.urner | last post by:
This archival (yet recent) posting to an obscure physics list might be of some interest to those taking a longer view. The work/study projects described below come from an Oregon think tank...
6
by: Steve | last post by:
Hello all: I am working on a project that has two list boxes side-by-side on a form. What I want to happen is when a user clicks on an item in the list box on the left, the list box on the...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.