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

Some complex structure I can't code correctly

Hello all, I've been trying to reengineer some C code to C++, but got
stuck on some complex data structure:

On the C code, there is an "Model" struct used to store various kind of
data, the exact kind stored in the "type" member. Each kind has
different data, that is stored in a "value" array. So, if a Model is
type "Car", the maximum speed is stored in value[0]. If it's a "House",
value[0] is used to store number of inhabitants. A huge mess!

Here comes C++ to the rescue, I created a ModelBase class, with
ModelCar, ModelHouse and so on as derived clases. All models have many
common data, so this polimorphism works very nicely.

However, there is also an "Obj" struct, which represents an instance of
the data stored in a "Model". In C, it is the same mess as with Model
("type" member, "value" array)... and along new data needed for all
Objs, it has a pointer back to the Model it originated from.

So I created a ObjBase clases, with ObjCat, ObjHouse deriving from it.

And here is the problem... each Model needs to "spawn" an Obj, using a
covariant return type function, such as:
ObjHouse* ModelHouse::spawn();
But also, each Obj needs to returns a reference to its Model, also
using covariant return type:
ModelHouse* ObjHouse::get_model();
I have this:

class Model;
class Obj {
virtual Model* get_model() = 0;
};
class Model {
virtual Obj* spawn() = 0;
};

class ModelHouse;
class ObjHouse : public Obj {
ModelHouse* get_model(); // <- ERROR HERE
};
class ModelHouse : public Model {
ObjHouse* spawn();
};

Error says "invald covariant return type". Of course, up to that point,
it doesn't know that ModelHouse derives from Model, but moving
ModelHouse before ObjHouse, gives a similar error for
ModelHouse::spawn.

Any clues on how to solve this? Some pattern to represent this data? I
have tried some ideas, but nothing works.

I'm using gcc 3.4.4, btw.

Thanks.

Jun 27 '06 #1
5 1461
* do****@gmail.com:
Hello all, I've been trying to reengineer some C code to C++, but got
stuck on some complex data structure:

On the C code, there is an "Model" struct used to store various kind of
data, the exact kind stored in the "type" member. Each kind has
different data, that is stored in a "value" array. So, if a Model is
type "Car", the maximum speed is stored in value[0]. If it's a "House",
value[0] is used to store number of inhabitants. A huge mess!

Here comes C++ to the rescue, I created a ModelBase class, with
ModelCar, ModelHouse and so on as derived clases. All models have many
common data, so this polimorphism works very nicely.

However, there is also an "Obj" struct, which represents an instance of
the data stored in a "Model". In C, it is the same mess as with Model
("type" member, "value" array)... and along new data needed for all
Objs, it has a pointer back to the Model it originated from.

So I created a ObjBase clases, with ObjCat, ObjHouse deriving from it.

And here is the problem... each Model needs to "spawn" an Obj, using a
covariant return type function, such as:
ObjHouse* ModelHouse::spawn();
But also, each Obj needs to returns a reference to its Model, also
using covariant return type:
ModelHouse* ObjHouse::get_model();
I have this:

class Model;
class Obj {
virtual Model* get_model() = 0;
};
class Model {
virtual Obj* spawn() = 0;
};

class ModelHouse;
class ObjHouse : public Obj {
ModelHouse* get_model(); // <- ERROR HERE
};
class ModelHouse : public Model {
ObjHouse* spawn();
};

Error says "invald covariant return type". Of course, up to that point,
it doesn't know that ModelHouse derives from Model, but moving
ModelHouse before ObjHouse, gives a similar error for
ModelHouse::spawn.

Any clues on how to solve this? Some pattern to represent this data? I
have tried some ideas, but nothing works.


The only you can benefit from the covariance is by statically knowing
the type of object, say, that you have pointer of static type ObjHouse*.
But in that case you can call a non-virtual function p->houseModel(),
so in the case where you can benefit from the covariance, you don't need
it: all you need in that case is a non-virtual function. For the other
cases you also need a virtual function, of unchanging signature.

If you plan on supporting derivation from concrete classes you should
let the non-virtual function call the virtual one and downcast the result.

That might sound counter-intuitive and downright "wrong", but instead of
writing umpteen hundred lines explaining it, I'll let you figure it out.

--
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?
Jun 27 '06 #2

<do****@gmail.com> wrote in message
news:11*********************@p79g2000cwp.googlegro ups.com...
Hello all, I've been trying to reengineer some C code to C++, but got
stuck on some complex data structure:

On the C code, there is an "Model" struct used to store various kind of
data, the exact kind stored in the "type" member. Each kind has
different data, that is stored in a "value" array. So, if a Model is
type "Car", the maximum speed is stored in value[0]. If it's a "House",
value[0] is used to store number of inhabitants. A huge mess!

Here comes C++ to the rescue, I created a ModelBase class, with
ModelCar, ModelHouse and so on as derived clases. All models have many
common data, so this polimorphism works very nicely.

However, there is also an "Obj" struct, which represents an instance of
the data stored in a "Model". In C, it is the same mess as with Model
("type" member, "value" array)... and along new data needed for all
Objs, it has a pointer back to the Model it originated from.

So I created a ObjBase clases, with ObjCat, ObjHouse deriving from it.

And here is the problem... each Model needs to "spawn" an Obj, using a
covariant return type function, such as:
ObjHouse* ModelHouse::spawn();
But also, each Obj needs to returns a reference to its Model, also
using covariant return type:
ModelHouse* ObjHouse::get_model();
I have this:

class Model;
class Obj {
virtual Model* get_model() = 0;
};
class Model {
virtual Obj* spawn() = 0;
};

class ModelHouse;
class ObjHouse : public Obj {
ModelHouse* get_model(); // <- ERROR HERE
};
class ModelHouse : public Model {
ObjHouse* spawn();
};

Error says "invald covariant return type". Of course, up to that point,
it doesn't know that ModelHouse derives from Model, but moving
ModelHouse before ObjHouse, gives a similar error for
ModelHouse::spawn.

Any clues on how to solve this? Some pattern to represent this data? I
have tried some ideas, but nothing works.

I'm using gcc 3.4.4, btw.

Thanks.


The way I would solve this is simply by returning a Model* in all cases.
Since ModelHouse derives from Model, you can point to a ModelHouse with a
Model pointer and use polymorphism.
Jun 27 '06 #3
do****@gmail.com wrote:

class Model;
class Obj {
virtual Model* get_model() = 0;
};
class Model {
virtual Obj* spawn() = 0;
};

class ModelHouse;
class ObjHouse : public Obj {
ModelHouse* get_model(); // <- ERROR HERE
};
class ModelHouse : public Model {
ObjHouse* spawn();
};


My advice would be :
class ModelHouse;
class ObjHouse : public Obj {
Model *get_model(); // <- ERROR HERE
};
class ModelHouse : public Model {
Obj* spawn();
};

then you can do a typecast after calling spawn and get_model.
Does that help ?

Regards
Thorsten

Jun 27 '06 #4
Alf P. Steinbach wrote:
The only you can benefit from the covariance is by statically knowing
the type of object, say, that you have pointer of static type ObjHouse*.
But in that case you can call a non-virtual function p->houseModel(),
so in the case where you can benefit from the covariance, you don't need
it: all you need in that case is a non-virtual function. For the other
cases you also need a virtual function, of unchanging signature.

If you plan on supporting derivation from concrete classes you should
let the non-virtual function call the virtual one and downcast the result.

That might sound counter-intuitive and downright "wrong", but instead of
writing umpteen hundred lines explaining it, I'll let you figure it out.


Sometimes I need to spawn a Model of unknown type. No derived class
info needed:

for ( Model* M = ... )
Obj* O = M->spawn();

But also, sometimes a specific kind of Model is spawned, and its unique
attributes changed:

ModelHouse* M = ...;
ObjHouse* O = M->spawn();
O->set_city("Athens");

Here I need spawn to use covariance, or dynamic_cast it (that I know
will always be successful, so a static_cast can be used). Or, instead
of "spawn", call a "spawnHouse" (ugly).
The other way around is also true: sometimes I have a big list of Obj*
and only the base class needs to be accessed, so get_model don't need
covariance.

for ( Obj* O = ... )
Model* M = O->get_model();

But other times, from a ObjCar I need its model...

ObjCar* O = ...;
ModelCar* M = O->get_model();
cout << M->get_max_speed();

Same as before: either use covariance on "get_model", or add a
"get_modelCar"... and the latter is way too ugly.

Jun 27 '06 #5
* do****@gmail.com:
Alf P. Steinbach wrote:
The only you can benefit from the covariance is by statically knowing
the type of object, say, that you have pointer of static type ObjHouse*.
But in that case you can call a non-virtual function p->houseModel(),
so in the case where you can benefit from the covariance, you don't need
it: all you need in that case is a non-virtual function. For the other
cases you also need a virtual function, of unchanging signature.

If you plan on supporting derivation from concrete classes you should
let the non-virtual function call the virtual one and downcast the result.

That might sound counter-intuitive and downright "wrong", but instead of
writing umpteen hundred lines explaining it, I'll let you figure it out.


Sometimes I need to spawn a Model of unknown type. No derived class
info needed:

for ( Model* M = ... )
Obj* O = M->spawn();

But also, sometimes a specific kind of Model is spawned, and its unique
attributes changed:

ModelHouse* M = ...;
ObjHouse* O = M->spawn();
O->set_city("Athens");

Here I need spawn to use covariance


No. Quoting myself, "in the case where you can benefit from the
covariance, you don't need it". Please read what you're responding to
before responding. You've got a solution. Now go implement it (come
back if you actually encounter a problem, not for some imagined need).

--
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?
Jun 27 '06 #6

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

Similar topics

4
by: PHPkemon | last post by:
Hi there, A few weeks ago I made a post and got an answer which seemed very logical. Here's part of the post: PHPkemon wrote: > I think I've figured out how to do the main things like...
5
by: Jeff | last post by:
I've created a beast! Here is my data structure: $VAR1 = 'bunkers'; $VAR2 = { 'items' => , \ ] }; $VAR3 = 'simpsons'; $VAR4 = {
0
by: Ivan | last post by:
Hi All, I have a problem with marshaling complex structures (containing numbers, strings, arrays of another structures) to native C function in dll. I have already posted same question to...
0
by: olafmol | last post by:
Hello, i have a problem using a .NET WSDL Webservice from PHP. Using both the NuSOAP lib for PHP4, and the build-in SOAP lib for PHP5 it seems that the SOAP client cannot pass a variable amount...
0
by: Kirk Marple | last post by:
i have a large C++ data structure that i'm trying to interop with... the structure is 77400 bytes long. i have the structure defined in C#, so i was trying to just use "ref <structure>" as the...
0
by: Ivan | last post by:
Hi All, I have a problem with marshaling complex structures (containing numbers, strings, arrays of another structures) to native C function in dll. I have already posted same question to...
6
by: Laurent | last post by:
Hello, This is probably a dumb question, but I just would like to understand how the C# compiler computes the size of the managed structure or classes. I'm working on this class: public...
21
by: Jim | last post by:
I am trying to write an HTTP/HTTPS proxy server in VB.Net 2005. But, I don't really even know how the internal workings of a proxy should act. Does anyone have anything on the protocols used in...
8
by: Eric bouxirot | last post by:
hi there, i never used XML beforre, i prefere INI files, but i want do same things with XML file format.. before i can save/read some element of INI files without the need to parse or read...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
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: 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: 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: 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
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.