class A {
public:
char text_a[100];
A() { *text_a=0; }
~A() {}
};
//-----------------------------------------------------------------------------
class B {
public:
char text_b[100];
B() { *text_b=0; }
~B() {}
};
//-----------------------------------------------------------------------------
class C : public A, public B {
public:
char text_c[100];
C() { *text_c=0; }
~C() {}
};
//-------------------------------------------------------------------------------
void test() {
B *bp1,*bp2;
C c,*cp1,*cp2,*cp 3;
void *p;
strcpy(c.text_a ,"hello a");
strcpy(c.text_b ,"hello b");
strcpy(c.text_c ,"hello c");
cp1=&c;
p=cp1;
bp1=cp1; // ok
bp2=(B*)p; // resulting bp2 is WRONG!
cp2=(C*)p; // ok
cp3=(C*)bp2; // resulting cp3 is WRONG! Which is logical because bp2
is already wrong.
}
//-----------------------------------------------------------------------------
So the hot spot is the bp2=(B*)p;
What's wrong with that???
I can imagine someone saying "p is not pointing to a B object".
But if you think about it, conceptually, it does, imho.
So is it more a technical matter of compiling this!?
Maybe i'm stupid and/or missing something essential about C++.
If so, please give me a link to where i can study this right.
Cheers,
Jo
Jun 18 '07
31 1928
James Kanze wrote:
>On Jun 18, 10:17 pm, Jo <j...@mutools.c omwrote:
>>John Harrison wrote:
[...]
>>>dynamic_ca st does do base to derived conversion, that's it's main use. Where are you getting your information?
>>I got that fromhttp://www.cplusplus.c om/doc/tutorial/typecasting.htm l
>>But i was just reading another webpage where they indeed use base-to-derived dynamic casts...
>>Did i misunderstand the cplusplus page?
You didn't read the sentence completely. It says: "The second conversion in this piece of code would produce a compilation error since base-to-derived conversions are not allowed with dynamic_cast UNLESS the base class is polymorphic." Note that final clause, with the unless. In their example, the base class didn't have any virtual functions, so using dynamic_cast to the derived would be a compiler error.
I understand.
>Generally speaking, you should avoid using void* as much as possible, and use dynamic_cast exclusively for moving between classes in a hierarchy. When you can't avoid void*, e.g. because of legacy or C interfaces, always cast back to exactly the type of pointer you originally had, then go from there. Note that often, this means casting to a specific type before casting to void*. For example (using pthread_create as an example, but it could be any C API function that takes a pointer to function and a void*):
class Thread
{
public:
virtual ~Thread() {}
virtual void* run() = 0 ;
} ;
extern "C"
void*
threadStarter( void* p )
{
Thread* t = static_cast< Thread* >( p ) ;
return t->run() ;
}
void
f()
{
// MyThread derives from Thread...
pthread_t t ;
pthread_create( &t, NULL, &threadStart er, new MyThread ) ;
}
As written, this is undefined behavior. The last code line must be:
pthread_create(
&t, NULL, &threadStart er, static_cast< Thread* >( new MyThread ) ) ;
(The problem is, that as it is undefined behavior, it might seem to work some of the time anyway. On most implementations , for example, it will seem to work as long as only single inheritance is involved.)
Indeed, and that's why i was so confused, because i've been using this
many times. (too many it seems now!)
I guess that, by coincidence, i never ran into the combination of using
a void* and multiple inherited objects, and so that's why i only
encountered the errors now.
I'm happy that this has been sorted out, and i completely understand the
reasons beyond it.
All sounds logical.
I'll avoid using void* as much as possible!
And i should use more static_cast / dynamic_cast instead of the old
c-style casts, because they're more error-conscious.
(a pity of that quircky syntax though)
Jo <jo@mutools.com wrote in
news:fY******** *************@p hobos.telenet-ops.be:
Andre Kostur wrote:
>>Jo <jo@mutools.com wrote in news:6G****** *************** @phobos.telenet-ops.be:
[snip]
>>However, a necessity to using dynamic_cast<te nds to indicate a potential flaw in your design. You should really be asking yourself why you need to know the derived type. Couldn't it be better implemented as a virtual function in the base class? So if the function you're attempting to call in C is already virtual in A, then you don't need explicitly know that you're working with a C object. Just call the function through the A* and let the compiler follow the virtual dispatch to call the real function.
Thought 1: If every very base class should foresee all virtual
functions that are coming down the hierarchic tree (or do they say
"up" the tree? still confused), then these base classes get much too
much cluttered with non-relevant virtual funcs!
Like most trees in computing, they're usually thought of as growing
downwards. So the most base class is usually written at the top, then
the next derived class below it, etc. Thus the terms "upcasting" and
"downcastin g" through an inheritance hierarchy. Upcasting is free,
downcasting requires a cast.
Note that I said "tends to indicate a potential flaw". There are cases
where it may make sense. I'm not sure I can explain how you'd know when
to use it.
Perhaps you really wanted composition where you're using inheritance?
Thought 2: If class C is derived from class A and B, both having
virtual funcs, and i have an A pointer to a C object, and need to call
a B func of the C object, then do you propose to copy all the virtuals
of B in A? I'm confident the answer is no.
No, but whatever function that's going to use the B functionality should
take a B* (or B&). Or perhaps the A class should really have a B as a
member, not as a parent. If you really need to access it through an A*,
perhaps the design is flawed.
So these are two common situations where i need to know what kind of
object i'm dealing with.
In fact, the two thoughts can be summarized to this common reason to
use RTTI: to avoid "virtual clutter".
My conclusion: If you think about it pure conceptually, i don't see
what's wrong with using RTTI.Using virtuals to avoid RTTI is one good
strategy. Using RTTI to avoid virtuals is another good strategy. It
are two equivalent techniques, imo, one better in situation a, the
other better in situation b.
You're blurring the idea of Object Oriented programming (not to say that
you must use OO, C++ supports multiparadigm programming...) . The idea
behind inheritance and virtual functions is that it should be eliminating
the need to know exactly which derived class you're dealing with. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: mike420 |
last post by:
In the context of LATEX, some Pythonista asked what the big
successes of Lisp were. I think there were at least three *big*
successes.
a. orbitz.com web site uses Lisp for algorithms, etc.
b. Yahoo store was originally written in Lisp.
c. Emacs
The issues with these will probably come up, so I might as well
mention them myself (which will also make this a more balanced
|
by: mike420 |
last post by:
Tayss wrote:
>
> app = wxPySimpleApp()
> frame = MainWindow(None, -1, "A window")
> frame.Show(True)
> app.MainLoop()
>
Why do you need a macro for that? Why don't you just write
|
by: AFN |
last post by:
I am running the code below to generate XML from a data table. But some
fields in the data table are Null for every record. Suppose field5 has a
null database value. I would expect to see:
<field5></field5> or <field5 />
but instead it doesn't even show the field at all for those records where
field5 is Null! Instead it just shows:
<field4>Whatever</field4>
|
by: Douglas Buchanan |
last post by:
Buttons don't work if form is opened on startup
A2k
If 'frmMain' is set to open by default at startup none of the buttons
work.
If 'frmMain' is opened from the database window then all the buttons
work.
The form's name ('frmMain') is selected from in the Startup dialog
box.
|
by: DFS |
last post by:
I'm unfortunately about to change, or sever, a two-year relationship with a
very slow-paying client.
Most of the 15 invoices I've sent them arrive 6 to 8 weeks late, and usually
only after repeated calls to the requesting client department, AP and
finally Legal. I really think they would never pay some of these invoices
if I didn't hound them. I don't have the time or energy or stress-handling
to make repeated collection calls and...
| |
by: Nashat Wanly |
last post by:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaskdr/html/askgui06032003.asp
Don't Lock Type Objects!
Why Lock(typeof(ClassName)) or SyncLock GetType(ClassName) Is Bad
Rico Mariani, performance architect for the Microsoft® .NET runtime
and longtime Microsoft developer, mentioned to Dr. GUI in an e-mail
conversation recently that a fairly common practice (and one that's,
unfortunately, described in some of our...
|
by: LP |
last post by:
I am using (trying to) CR version XI, cascading parameters feature works it
asks user to enter params. But if page is resubmitted. It prompts for params
again. I did set ReuseParameterValuesOnRefresh="True" in a viewer, but it
still doesn't work. Did anyone run into this problem. What's the solution?
Please help.
Thank you
|
by: Frank |
last post by:
I've done this a few times.
In a solution I have a project, Say P1, and need another project that will
contain much code that is similar to that of P1.
I hope no one gets hung up on why I don't somehow share the code.
So, I copy the folder P1 is in, change the new folder name, and is VS2005 to
change all occurrences of P1's name tp P2's name.
|
by: jehugaleahsa |
last post by:
Hello:
I had an hour-long discussion with my boss today. Last night, right
before I dozed off, I realized some of his code resulted in duplicate
processing. I tried to explain it to him and he kept saying, "I'm
afraid to say it's 'OK' to change it because everything I did was for
a reason." Well, I know better.
My boss' old code is written in some cryptic C file with Oracle
precompiler macros barfed all over it. Once I figured out how...
|
by: Nepomuk |
last post by:
You might have heard about Linux, but you don't know what it is? Or you know a few things about it, but they terrify you? Well, then this article is for you. Don't be afraid - Everyone can use Linux!
Part 1: What is Linux and why should I use it?
Linux is an Operating System (short: OS). OK, so what is an OS? Let me explain:
Nearly everybody knows Windows. But what exactly does it actually do?
Windows is an example for a OS and one of it's...
|
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,...
| |
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...
|
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...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
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
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
|
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...
| |