Hi,
Is this code okay and compliant with the standard. As far as I
understand it is correct but I just want to make sure.
Thank you,
Ben.
----
#include <iostream>
using namespace std;
class Base {
public:
typedef void (Base::*PMethod )(void);
void Invoke (PMethod p) {(this->*p)();}
};
class Derived : public Base {
public:
void Method (void) {cout << "Hello World" << endl;}
};
int main (void) {
Derived x;
// *** Is the static_cast correct here ? Or could this leads
// to undefined behavior on some platform / compiler ?
x.Invoke(static _cast<Base::PMe thod>(&Derived: :Method));
return 0;
} 6 1221
Ben Thomas wrote:
Hi,
Is this code okay and compliant with the standard. As far as I
understand it is correct but I just want to make sure.
Thank you,
Ben.
----
#include <iostream>
using namespace std;
class Base {
public:
typedef void (Base::*PMethod )(void);
void Invoke (PMethod p) {(this->*p)();}
};
class Derived : public Base {
public:
void Method (void) {cout << "Hello World" << endl;}
};
int main (void) {
Derived x;
// *** Is the static_cast correct here ? Or could this leads
// to undefined behavior on some platform / compiler ?
x.Invoke(static _cast<Base::PMe thod>(&Derived: :Method));
return 0;
}
Generally speaking, a member of derived is NOT a member of base,
and that's why the conversion does not exist, and you have to resort
to some tricks (like casts) to silence the compiler that complains
otherwise. The static cast (as I understand it) would be called for
if you have a pointer to member of 'Base' ('Base::*ptr'), somehow
it was converted to a pointer to a member of 'Derived' ('Derived::*')
and then your base wants to call it. Then, since _originally_ the
pointer *was* to a member of 'Base', you're ok to use 'static_cast'.
If the pointer *never was* to a member of 'Base', casting is *not*
the right thing to do. You're correct suspecting that the behaviour
is undefined.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
On 2007-09-21 16:36:43 -0400, "Victor Bazarov" <v.********@com Acast.netsaid:
>
The static cast (as I understand it) would be called for
if you have a pointer to member of 'Base' ('Base::*ptr'), somehow
it was converted to a pointer to a member of 'Derived' ('Derived::*')
and then your base wants to call it. Then, since _originally_ the
pointer *was* to a member of 'Base', you're ok to use 'static_cast'.
If the pointer *never was* to a member of 'Base', casting is *not*
the right thing to do. You're correct suspecting that the behaviour
is undefined.
More generally, once you cast it, you have to cast it back to its
original type to get well-defined behavior.
--
Pete
Roundhouse Consulting, Ltd. ( www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
( www.petebecker.com/tr1book)
On Sep 21, 10:36 pm, "Victor Bazarov" <v.Abaza...@com Acast.netwrote:
Ben Thomas wrote:
Is this code okay and compliant with the standard. As far as I
understand it is correct but I just want to make sure.
#include <iostream>
using namespace std;
class Base {
public:
typedef void (Base::*PMethod )(void);
void Invoke (PMethod p) {(this->*p)();}
};
class Derived : public Base {
public:
void Method (void) {cout << "Hello World" << endl;}
};
int main (void) {
Derived x;
// *** Is the static_cast correct here ? Or could this leads
// to undefined behavior on some platform / compiler ?
x.Invoke(static _cast<Base::PMe thod>(&Derived: :Method));
return 0;
}
Generally speaking, a member of derived is NOT a member of base,
and that's why the conversion does not exist, and you have to resort
to some tricks (like casts) to silence the compiler that complains
otherwise. The static cast (as I understand it) would be called for
if you have a pointer to member of 'Base' ('Base::*ptr'), somehow
it was converted to a pointer to a member of 'Derived' ('Derived::*')
and then your base wants to call it. Then, since _originally_ the
pointer *was* to a member of 'Base', you're ok to use 'static_cast'.
If the pointer *never was* to a member of 'Base', casting is *not*
the right thing to do. You're correct suspecting that the behaviour
is undefined.
I think you've got it backwards. Pointer to member casts work
the opposite of normal pointer casts. There is an implicit D::*
to B::* conversion (no cast needed). A static_cast is needed
for D::* to B::*, however, and the using it is only legal if the
B it is used with is actually a D. Which is the case above. So
while the above may be as ugly as sin, it is perfectly legal
(and was used for callbacks in one GUI library---XViews, I
think---that was widely used in the past).
--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
James Kanze wrote:
On Sep 21, 10:36 pm, "Victor Bazarov" <v.Abaza...@com Acast.netwrote:
>Ben Thomas wrote:
>>Is this code okay and compliant with the standard. As far as I understand it is correct but I just want to make sure.
>>#include <iostream> using namespace std;
>>class Base { public: typedef void (Base::*PMethod )(void); void Invoke (PMethod p) {(this->*p)();} };
>>class Derived : public Base { public: void Method (void) {cout << "Hello World" << endl;} };
>>int main (void) { Derived x; // *** Is the static_cast correct here ? Or could this leads // to undefined behavior on some platform / compiler ? x.Invoke(static _cast<Base::PMe thod>(&Derived: :Method)); return 0; }
>Generally speaking, a member of derived is NOT a member of base, and that's why the conversion does not exist, and you have to resort to some tricks (like casts) to silence the compiler that complains otherwise. The static cast (as I understand it) would be called for if you have a pointer to member of 'Base' ('Base::*ptr'), somehow it was converted to a pointer to a member of 'Derived' ('Derived::*') and then your base wants to call it. Then, since _originally_ the pointer *was* to a member of 'Base', you're ok to use 'static_cast'. If the pointer *never was* to a member of 'Base', casting is *not* the right thing to do. You're correct suspecting that the behaviour is undefined.
I think you've got it backwards. Pointer to member casts work
the opposite of normal pointer casts. There is an implicit D::*
to B::* conversion (no cast needed).
Nope. *You* got it backwards. Every member of 'B' is a member of
'D' as well (by inheritance), so 'B::*' =='D::*' requires no special
syntax, its implicit (modulo all the "available" and "unambiguou s"
cruft). [conv.mem]/2.
For the pointers to *objects*, however, it's reverse: Every 'D' is
a 'B' (modulo "available" and "unambiguou s"), so conversion from 'D*'
to 'B*' is implicit.
A static_cast is needed
for D::* to B::*, however, and the using it is only legal if the
B it is used with is actually a D. Which is the case above. So
while the above may be as ugly as sin, it is perfectly legal
(and was used for callbacks in one GUI library---XViews, I
think---that was widely used in the past).
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
On Sep 24, 3:59 pm, "Victor Bazarov" <v.Abaza...@com Acast.netwrote:
James Kanze wrote:
On Sep 21, 10:36 pm, "Victor Bazarov" <v.Abaza...@com Acast.netwrote:
[...]
Generally speaking, a member of derived is NOT a member of base,
and that's why the conversion does not exist, and you have to resort
to some tricks (like casts) to silence the compiler that complains
otherwise. The static cast (as I understand it) would be called for
if you have a pointer to member of 'Base' ('Base::*ptr'), somehow
it was converted to a pointer to a member of 'Derived' ('Derived::*')
and then your base wants to call it. Then, since _originally_ the
pointer *was* to a member of 'Base', you're ok to use 'static_cast'.
If the pointer *never was* to a member of 'Base', casting is *not*
the right thing to do. You're correct suspecting that the behaviour
is undefined.
I think you've got it backwards. Pointer to member casts work
the opposite of normal pointer casts. There is an implicit D::*
to B::* conversion (no cast needed).
Nope. *You* got it backwards. Every member of 'B' is a member of
'D' as well (by inheritance), so 'B::*' =='D::*' requires no special
syntax, its implicit (modulo all the "available" and "unambiguou s"
cruft). [conv.mem]/2.
For the pointers to *objects*, however, it's reverse: Every 'D' is
a 'B' (modulo "available" and "unambiguou s"), so conversion from 'D*'
to 'B*' is implicit.
Yes. There's a mix of misunderstandin g what you wrote, and
mistyping what I wanted to say, there. What I wanted to say was
that the implicit conversions go in the opposite sense for
pointers to members, compared to pointers to objects (which you
just said in a lot clearer form), but that just like pointers to
objects, you can static_cast in the opposite sense of the
implicit conversion, *provided* the actual type is really a
derived; i.e. Base* -Derived* is legal if the object pointed
to by Base* is actually a Derived, and Derived::* to Base::* is
legal if the resulting pointer to member is only used with the
address of a Base which is actually a Derived.
So you were wrong concerning undefined behavior. But to be
quite frank, I also thought it was undefined until I ran into a
large code base which used it.
--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
On Sep 21, 11:22 pm, Pete Becker <p...@versatile coding.comwrote :
On 2007-09-21 16:36:43 -0400, "Victor Bazarov" <v.Abaza...@com Acast.netsaid:
The static cast (as I understand it) would be called for
if you have a pointer to member of 'Base' ('Base::*ptr'), somehow
it was converted to a pointer to a member of 'Derived' ('Derived::*')
and then your base wants to call it. Then, since _originally_ the
pointer *was* to a member of 'Base', you're ok to use 'static_cast'.
If the pointer *never was* to a member of 'Base', casting is *not*
the right thing to do. You're correct suspecting that the behaviour
is undefined.
More generally, once you cast it, you have to cast it back to its
original type to get well-defined behavior.
Not really. Consider:
struct Base
{
virtual ~Base() {}
} ;
struct Derived1 : public Base
{
int i ;
} ;
struct Derived2 : public Base
{
double d ;
} ;
int Base::* pmi = static_cast< int Base::* >( &Derived1::i ) ;
Base* pd1 = new Derived1 ;
Base* pd2 = new Derived2 ;
pd1->*pmi = 42 ; // legal and well defined
pd2->*pmi = 42 ; // undefined behavior.
--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Thomas Matthews |
last post by:
Hi,
Given a structure of pointers:
struct Example_Struct
{
unsigned char * ptr_buffer;
unsigned int * ptr_numbers;
};
And a function that will accept the structure:
|
by: ozbear |
last post by:
This is probably an obvious question.
I know that pointer comparisons are only defined if the two pointers
point somewhere "into" the storage allocated to the same object, or if
they are NULL, or one-past the end of the object as long as it isn't
dereferenced.
I use "object" in the standard 'C' sense.
Is there some special dispensation given to comparing two pointers
|
by: brian |
last post by:
Quick question:
if I have a structure:
struct foo {
unsigned char *packet;
unsigned char *ip_src;
};
|
by: sunglo |
last post by:
Some time a go, in a discussion here in comp.lang.c, I learnt that it's
better not to use a (sometype **) where a (void **) is expected (using
a cast). Part of the discussion boiled down to the rule: if I cast a
(sometype **) to a (void **) I am making a number of assumptions about
the implementation's (void **) representation and length. Specifically,
if I do the above cast I'm assuming that a (sometype **) and a (void
**) have the same...
|
by: andy_dufresne |
last post by:
have posted the question here:
http://groups.google.com/group/programpara/browse_thread/thread/75b58c897f890930
| |
by: Joe Van Dyk |
last post by:
Is there some rule of thumb about when to use pointers to an object and
when to use a reference* to an object when a class needs to have objects
as data members?
Example:
class A
{
B* b_ptr;
B b;
vector<B*> vector_ptrs;
|
by: chankl |
last post by:
Can anyone explain what's an opaque pointer and how it's implemented in
C?
I read about this concept in the book "C interfaces and
implementations".
Here's an example from the book (list.h - available from the website):
#define T List_T
|
by: Praveen |
last post by:
Hi,
I came across a program as follows
main()
{
int x, y ;
int *p1 = &x;
int *p2 = &y;
printf("%d\n", p1-p2);
}
|
by: J Caesar |
last post by:
In C you can compare two pointers, p<q, as long as they come from the
same array or the same malloc()ated block. Otherwise you can't.
What I'd like to do is write a function
int comparable(void *p, void *q)
that will take any two pointers and decide whether they can be compared
or not.
I really can't think how to do this - any suggestions?
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
|
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...
| |
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: 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...
|
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...
|
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: 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...
| |