473,770 Members | 4,355 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

void* operations

Hi,
I haven't done a lot of C++ programming (done a lot of it in C) and the
reason why I'm considering switching now is also the question I'm
posting here.

I have some library functions that return to me a void* to data that
has been specifed by the user. There are also functions that return an
enum which contains information about the data type of this data. So
what I've done in the past is made a switch case statement based on the
data type enum and then explicitly re-cast the void* to the appropriate
data type.

Now I have a case where I have two values and each of them could be any
data type. Lets say I have to multiply them. So if I was to use my
usual method I'd have a switch case statement with numDataType(C)2
(combination) cases. Does C++ have a better way of extracting data from
void*?

Thanks for your help,
Ashish.

Feb 17 '06 #1
21 2339
as************* **@gmail.com wrote:
I haven't done a lot of C++ programming (done a lot of it in C) and
the reason why I'm considering switching now is also the question I'm
posting here.

I have some library functions that return to me a void* to data that
has been specifed by the user. There are also functions that return an
enum which contains information about the data type of this data. So
what I've done in the past is made a switch case statement based on
the data type enum and then explicitly re-cast the void* to the
appropriate data type.

Now I have a case where I have two values and each of them could be
any data type. Lets say I have to multiply them. So if I was to use my
usual method I'd have a switch case statement with numDataType(C)2
(combination) cases. Does C++ have a better way of extracting data
from void*?


"Better" in what sense?

V
--
Please remove capital As from my address when replying by mail
Feb 18 '06 #2
as************* **@gmail.com wrote:
Hi,
I haven't done a lot of C++ programming (done a lot of it in C) and the
reason why I'm considering switching now is also the question I'm
posting here.

I have some library functions that return to me a void* to data that
has been specifed by the user. There are also functions that return an
enum which contains information about the data type of this data. So
what I've done in the past is made a switch case statement based on the
data type enum and then explicitly re-cast the void* to the appropriate
data type.

Now I have a case where I have two values and each of them could be any
data type. Lets say I have to multiply them. So if I was to use my
usual method I'd have a switch case statement with numDataType(C)2
(combination) cases. Does C++ have a better way of extracting data from
void*?

Yes, don't!

Return a pointer to a base type and derive all your data classes from
it. A case of refactoring from switch to polymorphism.

class Base
{
virtual ~base() {}
...
};

class Data1 : public Base
{
....
};

....

--
Ian Collins.
Feb 18 '06 #3

Victor Bazarov wrote:
as************* **@gmail.com wrote:
I haven't done a lot of C++ programming (done a lot of it in C) and
the reason why I'm considering switching now is also the question I'm
posting here.

I have some library functions that return to me a void* to data that
has been specifed by the user. There are also functions that return an
enum which contains information about the data type of this data. So
what I've done in the past is made a switch case statement based on
the data type enum and then explicitly re-cast the void* to the
appropriate data type.

Now I have a case where I have two values and each of them could be
any data type. Lets say I have to multiply them. So if I was to use my
usual method I'd have a switch case statement with numDataType(C)2
(combination) cases. Does C++ have a better way of extracting data
from void*?


"Better" in what sense?

V
--
Please remove capital As from my address when replying by mail


Victor, "better way" in the sense that will it be possible for me to
define some sort of template or something else that will alow me to
have a common function that can be called with a void* irrespective of
the data type of the data that the pointer actually points to.

Ashish.

Feb 18 '06 #4

Ian Collins wrote:
as************* **@gmail.com wrote:
Hi,
I haven't done a lot of C++ programming (done a lot of it in C) and the
reason why I'm considering switching now is also the question I'm
posting here.

I have some library functions that return to me a void* to data that
has been specifed by the user. There are also functions that return an
enum which contains information about the data type of this data. So
what I've done in the past is made a switch case statement based on the
data type enum and then explicitly re-cast the void* to the appropriate
data type.

Now I have a case where I have two values and each of them could be any
data type. Lets say I have to multiply them. So if I was to use my
usual method I'd have a switch case statement with numDataType(C)2
(combination) cases. Does C++ have a better way of extracting data from
void*?

Yes, don't!

Return a pointer to a base type and derive all your data classes from
it. A case of refactoring from switch to polymorphism.

class Base
{
virtual ~base() {}
...
};

class Data1 : public Base
{
...
};

...

--
Ian Collins.


I'm sorry Ian but I have no idea what you just said, as I mentioned
before I don't have much C++ knowledge. Could you please elaborate a
little more? And maybe suggest some of the things I should be reading
up to do this; virtual seems to be something I should learn more about.

Thanks,
Ashish

Feb 18 '06 #5
Praetorian wrote:
[redacted]

I'm sorry Ian but I have no idea what you just said, as I mentioned
before I don't have much C++ knowledge. Could you please elaborate a
little more? And maybe suggest some of the things I should be reading
up to do this; virtual seems to be something I should learn more about.

The canonical example is a drawing program with shapes.

class Shape {
public:
virtual void Draw();
// other methods redacted
};

class Circle : public Shape {
public:
void Draw();
// other methods redacted
};

class Rectangle : public Shape {
public:
void Draw();
// other methods redacted
};

Now, you can just keep track of Shape*'s. Since you're not familiar
with C++, I'll use an array (yes, C++ people, I know he should use a
vector, and yes, I know there's likely memory leaks in the sample).

Shape* shapes[NSHAPES];

// reads shapes from a file.
int ReadShapes(Shap e* shapelist[], int max_shapes);

int main()
{
int n = ReadShapes(shap es, NSHAPES);

for (int i = 0; i < n ; ++i)
shapes[i]->Draw();
}

In this example, you don't have to worry about what kind of shape each
element of the array "shapes" is. Each element "knows" what kind of
data it is and does the right thing when asked to draw itself.

That's a very simplified example of polymorphism. Shape is the base
class, and Circle and Rectangle are derived classes. That's what Ian
was talking about. Instead of returning void* and having a switch
statement from hell, you create a class hierarchy with virtual
functions, return a pointer (or a reference) to the base class, and call
the virtual function, which "knows what to do".

I highly recommend getting "Accelerate d C++" by Koenig and Moo.

Feb 18 '06 #6
> I'm sorry Ian but I have no idea what you just said, as I mentioned
before I don't have much C++ knowledge. Could you please elaborate a
little more? And maybe suggest some of the things I should be reading
up to do this; virtual seems to be something I should learn more about.

Thanks,
Ashish


Let's say you have a bunch of methods of transportation represented as
types (e.g. bus, taxi, train, car, tram, etc) and despite all the
differences in between, all of them can be started and stopped.

What C++ allows you to do, is to start and/or stop any type of
transportation without knowing which type it is. What you do is you put
functions start and stop in a base class and derive all other
transportation from that class:

class transport
{
public:
virtual void start(void) = 0;
virtual void stop (void) = 0;

virtual ~transport(); // destructor
};

class bus: public transport
{
public:
void start(void)
{
signal_passenge rs();
close_the_doors ();
log_timetable() ;
ignite_engine() ;
// ...
}

void stop(void)
{
apply_brake();
open_the_doors( );
wait_for_passen gers_to_get_off ();
log_time_table( );
switch_off_engi ne();
}

// also a bunch of bus-specific features...
};

class taxi: public transport
{
public:
void start(void)
{
start_mile_coun ter();
say_hello_to_pa ssenger();
ask_for_destina tion();
off_you_go();
}

void stop(void)
{
apply_brake();
get_paid();
say_goodbye();
}

// also a bunc of taxi-specific features...
};

Now a bus* pointer is also a transport* pointer; a taxi* is also a
transport*; etc. So you can do someting like:

int main()
{
transport* t;
taxi my_favorite;
bux my_second_favor ite;

t = &my_favorite ;
t->start(); // starts a taxi
t->stop(); // stops a taxi

t = &my_second_favo rite;
t->start(); // starts a bus
t->stop(); // stops a bus
}

Well, if you have no clue what I am talking about I strongly recommend
you to grab a C++ book and read on classes and derived classes.

Regards,
Ben
Feb 18 '06 #7
Praetorian wrote:

I'm sorry Ian but I have no idea what you just said, as I mentioned
before I don't have much C++ knowledge. Could you please elaborate a
little more? And maybe suggest some of the things I should be reading
up to do this; virtual seems to be something I should learn more about.

Oh dear, you should get yourself a couple of decent C++ books,
"Accelerate d C++" and "The C++ programming language, 3rd edition" are a
good start.

A very common way to replace C style switches is to use polymorphic
types and virtual methods. You must understand these concepts, a simple
google for "polymorphi c virtual C++" should get you started.

Welcome to the fun world of C++.

--
Ian Collins.
Feb 18 '06 #8
Praetorian wrote:
Victor Bazarov wrote:
as************* **@gmail.com wrote:
I haven't done a lot of C++ programming (done a lot of it in C) and
the reason why I'm considering switching now is also the question
I'm posting here.

I have some library functions that return to me a void* to data that
has been specifed by the user. There are also functions that return
an enum which contains information about the data type of this
data. So what I've done in the past is made a switch case statement
based on the data type enum and then explicitly re-cast the void*
to the appropriate data type.

Now I have a case where I have two values and each of them could be
any data type. Lets say I have to multiply them. So if I was to use
my usual method I'd have a switch case statement with
numDataType(C)2 (combination) cases. Does C++ have a better way of
extracting data from void*?


"Better" in what sense?

V
--
Please remove capital As from my address when replying by mail


Victor, "better way" in the sense that will it be possible for me to
define some sort of template or something else that will alow me to
have a common function that can be called with a void* irrespective of
the data type of the data that the pointer actually points to.


Apparently, your 'void*' only designates the address of some memory
area. If the object that occupies that memory has been successfully
constructed by those "library functions", then you can simply _cast_
the pointer to the pointer to the type as indicated by that enum.
You can use 'static_cast'.

If your memory area does _not_ contain a successfully constructed object,
then the cast doesn't help. However, you probably know the layout of
the memory, so you can easily write the algorithm of "recreating " the
objects. I strongly recommend letting the objects construct themselves
by having properly defined _explicit_ constructors to which you will
pass the void*.

Having re-read your post, I am still unable to understand what it is
you do not like about "recasting" as you put it. If you're stuck with
those library functions, there is no simpler or more straightforward
way.

V
--
Please remove capital As from my address when replying by mail
Feb 18 '06 #9

Victor Bazarov wrote:
Praetorian wrote:
Victor Bazarov wrote:
as************* **@gmail.com wrote:
I haven't done a lot of C++ programming (done a lot of it in C) and
the reason why I'm considering switching now is also the question
I'm posting here.

I have some library functions that return to me a void* to data that
has been specifed by the user. There are also functions that return
an enum which contains information about the data type of this
data. So what I've done in the past is made a switch case statement
based on the data type enum and then explicitly re-cast the void*
to the appropriate data type.

Now I have a case where I have two values and each of them could be
any data type. Lets say I have to multiply them. So if I was to use
my usual method I'd have a switch case statement with
numDataType(C)2 (combination) cases. Does C++ have a better way of
extracting data from void*?

"Better" in what sense?

V
--
Please remove capital As from my address when replying by mail


Victor, "better way" in the sense that will it be possible for me to
define some sort of template or something else that will alow me to
have a common function that can be called with a void* irrespective of
the data type of the data that the pointer actually points to.


Apparently, your 'void*' only designates the address of some memory
area. If the object that occupies that memory has been successfully
constructed by those "library functions", then you can simply _cast_
the pointer to the pointer to the type as indicated by that enum.
You can use 'static_cast'.

If your memory area does _not_ contain a successfully constructed object,
then the cast doesn't help. However, you probably know the layout of
the memory, so you can easily write the algorithm of "recreating " the
objects. I strongly recommend letting the objects construct themselves
by having properly defined _explicit_ constructors to which you will
pass the void*.

Having re-read your post, I am still unable to understand what it is
you do not like about "recasting" as you put it. If you're stuck with
those library functions, there is no simpler or more straightforward
way.

V
--
Please remove capital As from my address when replying by mail


Thank you for all of your replies; and I have been busy Google searches
for C++ tutorials since my last post; in fact I was just about to read
about virtual functions when I decided to check this posting again.

Victor, the void* returned to me does point to a successfully
constructed object in memory, having the size of whatever the data type
enum; I can simply re-cast to the data type pointer and access it
without worrying about any kind of memory corruption (thank God for
that). Let me try and illustrate my problem with explicit casting using
an example:

Let's say I have 2 values that I need to multiply and each value may be
an int16 or an int32. I have void pointers v1 and v2 to each. So the
way I see what I need to do is something like:

if(d1 == INT16 && d2 == INT16)
{
v1int16 = (int16 *)v1;
v2int16 = (int16 *)v2;
output = v1*v2;
}
else if(d1 == INT16 && d2 == INT32)
{
v1int16 = (int16 *)v1;
v2int32 = (int32 *)v2;
output = v1*v2;
}
else if(d1 == INT32 && d2 == INT16)
{ .....}
else
{......}

Now this becomes rather tedious because I need to support 10 different
data types and I have to operate on 3 values instead of 2; basically a
switch case or if else construct from hell as someone put it in an
earlier post.

Although the virtual function method looks promising doesn't that still
mean I need to have a function for each combination of data types? I
was looking into templates but even with them the problem is that my
knowledge of the data type lies in an enum value and I don't know how
to incorporate this in a template; maybe a template which does the
final operation on pointers and virtual functions to 'condition' the
values based on their data types, if any conditioning is needed. These
functions would return pointers that can be used by the template.

I'm just throwing out ideas here and forgive me if I've managed to
sound stupid with my solution. You guys should be able to suggest
something that works for me.

Thanks,
Ashish.

Feb 18 '06 #10

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

Similar topics

5
2371
by: trying_to_learn | last post by:
Hello All Have another qn from the practice exercises. I ve done the exercise and the birds fly member fn was called successfully. But i still cant answer the authors qn. why this ability to assign void * has had to be avoided in C++. I didnt even instantiate bird obj then how was i able to call a bird member fn. Im confused. Quote: "Qn)Create a class called bird that can fly( ) and a class rock that can’t. Create a rock object, take...
6
9145
by: dam_fool_2003 | last post by:
Hai, I thank those who helped me to create a single linked list with int type. Now I wanted to try out for a void* type. Below is the code: #include<stdlib.h> #include<stdio.h> #include<string.h> #include<stddef.h> struct node
15
4165
by: Stig Brautaset | last post by:
Hi group, I'm playing with a little generic linked list/stack library, and have a little problem with the interface of the pop() function. If I used a struct like this it would be simple: struct node { struct node *next; void *data; };
2
1732
by: Xiangliang Meng | last post by:
Hi, all. As far as I know, the speical arithmetic operator on void pointer is an externsion in GNU CC. However, I could not find the relative topics in C99. Would someone like to help me find them out? in linux\mm\Slab.c, typedef struct slab_s { struct list_head list; unsigned long colouroff;
27
8975
by: Erik de Castro Lopo | last post by:
Hi all, The GNU C compiler allows a void pointer to be incremented and the behaviour is equivalent to incrementing a char pointer. Is this legal C99 or is this a GNU C extention? Thanks in advance. Erik
14
3024
by: arun | last post by:
Hi, Why sizeof operator when applied on void returns one when compiled with gcc compiler ??. When i tried it on VC++ compiler, it gives an error. But another version of the VC++ compiler on my friend's machine gives it as zero. Have anyone tried this ? I believe it should give an error because i think there is nothing called void. Regards, arun..
18
2140
by: Giannis Papadopoulos | last post by:
According to the standard (ISO C99 draft WG14/N1124), void is the incomplete type that cannot be completed and comprises the empty set of values. Since it declares the absense of a value can it be considered a data type? Regarding void*, is it just a simple reuse of the same keyword (void) or they have a closer relationship? I could think of only one - a pointer to an incomplete type. However, if one could say that void is the absense...
18
1818
by: hyderabadblues | last post by:
What does (void) poService in followinf peace of code mean tclCtrlBoard::tclCtrlBoard( void* poService ) { # if defined Something (void) poService; \\ What does this mean }
16
2702
by: PeterAPIIT | last post by:
Hello all C++ expert programmer, i have wrote partial general allocator for my container. After reading standard C++ library and code guru article, i have several questions. 1. Why allocator write forward declaration then allocation for void* rather than directly wrote allocator first ?
0
9439
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 synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10237
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. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10071
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 captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9882
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 choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8905
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 launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7431
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5467
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3987
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
3
2832
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.