Different Objects in Array

I

Immortal Nephi

I thought that you might find an interesting code. Perhaps, you have
seen this before. I created two classes of A and B. Two classes have
different objects. The class Obj has a relationship to class A and
class B which is called composition.
The class Obj has one variable which is a pointer to member function
in array. You can't bind member function of both class A and class B
because they do not belong to class Obj. I use reinterpret_cast to
convert from class A to class Obj before pointer to member function is
invoked.
I believe that my code is the alternative replacement so I don't use
inheritance and polymorphism. It is easier to extract class. What do
you think?

For example:

class A
{
public:
A() : x( 10 ) {}
~A() {}

void Run() { x++; cout << "A: " << x << endl; }

private:
int x;
};

class B
{
public:
B() : y( 20 ) {}
~B() {}

void Run() { y++; cout << "B: " << y << endl; }

private:
int y;
};

class Obj
{
public:
Obj() {}
~Obj() {}

void Run()
{
( this->*pO[0] )();
( this->*pO[1] )();
}

private:
A a;
B b;
typedef void ( Obj::*To )();
static To const pO[2];
};

Obj::To const Obj::pO[2] =
{
reinterpret_cast< To >( &A::Run ),
reinterpret_cast< To >( &B::Run )
};

int main()
{
Obj o;
o.Run();

return 0;
}
 
V

Victor Bazarov

Immortal said:
I thought that you might find an interesting code. Perhaps, you have
seen this before. I created two classes of A and B. Two classes have
different objects. The class Obj has a relationship to class A and
class B which is called composition.
The class Obj has one variable which is a pointer to member function
in array. You can't bind member function of both class A and class B
because they do not belong to class Obj. I use reinterpret_cast to
convert from class A to class Obj before pointer to member function is
invoked.
I believe that my code is the alternative replacement so I don't use
inheritance and polymorphism. It is easier to extract class. What do
you think?

Your code has undefined behaviour, not to mention that the compiler that
is supposed to compile your 'reinterpret_cast' will exhibit undefined
behaviour (most likely). Aside from that, you're good...
For example:

class A
{
public:
A() : x( 10 ) {}
~A() {}

void Run() { x++; cout << "A: " << x << endl; }

private:
int x;
};

class B
{
public:
B() : y( 20 ) {}
~B() {}

void Run() { y++; cout << "B: " << y << endl; }

private:
int y;
};

class Obj
{
public:
Obj() {}
~Obj() {}

void Run()
{
( this->*pO[0] )();
( this->*pO[1] )();
}

private:
A a;
B b;
typedef void ( Obj::*To )();
static To const pO[2];
};

Obj::To const Obj::pO[2] =
{
reinterpret_cast< To >( &A::Run ),
reinterpret_cast< To >( &B::Run )
};

int main()
{
Obj o;
o.Run();

return 0;
}

V
 
I

Immortal Nephi

Your code has undefined behaviour, not to mention that the compiler that
is supposed to compile your 'reinterpret_cast' will exhibit undefined
behaviour (most likely).  Aside from that, you're good...

Hi Victor,

How did you say undefined behavior? I played with debugging. I found
out that reinterpret_cast array did assign memory address correctly,
but *this* pointer in class A and class B assigns to the wrong memory
address.

For example:

class ....
{
int a;
int b;
int c;
}

*this* pointer should always assigns to data member as a, but it did
assigns to either data member as b or c. The data was misplaced from
a to b like memory misalignment.

I guess there is no alternative replacement to undefined
reinterpret_cast array, but switch block is the answer to each class'
member function.

Do you know if there is another way? What about template array?
 
L

LR

Immortal said:
Hi Victor,

How did you say undefined behavior? I played with debugging. I found
out that reinterpret_cast array did assign memory address correctly,
but *this* pointer in class A and class B assigns to the wrong memory
address.

5.2.10.9 in the 98 standard makes me think the cast you used is
unspecified behavior.

From N2857, (it's easier to copy)

5.5 Pointer-to-member operators [expr.mptr.oper]

3 The binary operator ->* binds its second operand, which shall be of
type “pointer to member of T” (where T is a completely-defined effective
class type) to its first operand, which shall be of type “pointer to T”
or “pointer to a class of which T is an unambiguous and accessible base
class.” The result is an object or a function of the type specified by
the second operand.

Obj is not a base class of either A or B, so both calls would appear to
be non compliant.

What do you mean by wrong memory address?

I tried running the code you posted and this was the output:
A: 11
B: 12


Here Obj::Run from your previous post.

void Obj::Run() {
( this->*pO[0] )();
( this->*pO[1] )();
}

My compiler is sort of doing what you asked it to do. First it calls
A::Run and then B::Run, but both times it is using your instance of Obj.
*Luckily*, the first object in Obj is an instance of A, a, so the first
call does what you expect. The second call also modifies Obj::A a, but
does it by calling B::Run, because the this pointer you are calling
B::Run with is for your instance of Obj.

I changed the code you posted by adding an int, k, before Obj::A a in
Obj and changing Obj::Obj() to initialize k to -22. This changed the
output to:
A: -21
B: -20

But I suspect this is all unpredictable and your compiler will vary.
I guess there is no alternative replacement to undefined
reinterpret_cast array, but switch block is the answer to each class'
member function.

It isn't clear to me what you hope to accomplish.
Do you know if there is another way? What about template array?

Have you taken a look at boost variant?
http://www.boost.org/doc/libs/1_41_0/doc/html/variant.html

Or perhaps you might consider something like this:

class Obj {
public:
Obj() {}
~Obj() {}
private:
void RunA() {
a.Run();
}
void RunB() {
b.Run();
}
typedef void (Obj::*MFP)();
const std::vector<MFP> &GetMFP() const {
static const MFP a[] = { &Obj::RunA, &Obj::RunB };
static const std::vector<MFP> v(a,a+sizeof(a)/sizeof(a[0]));
return v;
}
public:
void Run() {
const std::vector<MFP> &v = GetMFP();
for(size_t i=0; i<v.size(); i++) {
(this->*v)();
}
}
private:
A a;
B b;
};

LR
 
B

Balog Pal

Immortal Nephi said:
How did you say undefined behavior? I played with debugging. I found
out that reinterpret_cast array did assign memory address correctly,
but *this* pointer in class A and class B assigns to the wrong memory
address.

It assigns the "correct" addres as in "does as you command".
And assign an incorrect address as in "nothing like the called function
would want".

So no wander it doesn't work, or if looks like works, it is only a strange
accident.

void Run()
{
( this->*pO[0] )();
( this->*pO[1] )();
}

should really look like

((this->a).* reintepret_cast< ( A::*)()>( pO[0]))();
((this->b).* reintepret_cast< ( B::*)()>( pO[1]))();

and even for that I'm not sure that this kind of round-trip is guaranteed
for ptm-s. Better chance if the intermediate type is int or long -- if the
compiler accepts it could work too.

( reintepret_cast<Obj*)(&a)->a *pO[0] )();

( reintepret_cast<Obj*)(&b)->a *pO[1] )();

might have certain chance to hit the bull for some implementations.

Forget it. Rather tell what you want to achieve.
 
M

Michael Doubez

Hi Victor,

How did you say undefined behavior?  I played with debugging.  I found
out that reinterpret_cast array did assign memory address correctly,
but *this* pointer in class A and class B assigns to the wrong memory
address.

For example:

class ....
{
int a;
int b;
int c;

}

*this* pointer should always assigns to data member as a, but it did
assigns to either data member as b or c.  The data was misplaced from
a to b like memory misalignment.

I guess there is no alternative replacement to undefined
reinterpret_cast array, but switch block is the answer to each class'
member function.

Do you know if there is another way?  What about template array?

You can use union:

class Obj
{
public:
void Run()
{
this->*(pO[0].runA)();
this->*(pO[1].runB)();
}

private:
A a;
B b;
union To
{
void A::*runA();
void B::*runB();
};
static To const pO[2];

};

// not sure about initialisation - perhaps only possible in C99
Obj::To const Obj::pO[2] =
{
{&A::Run},
{&B::Run}
};
 
J

James Kanze

Your code has undefined behaviour, not to mention that the
compiler that is supposed to compile your 'reinterpret_cast'
will exhibit undefined behaviour (most likely). Aside from
that, you're good...

His reinterpret_cast are legal and well behaved. His problem is
that the only thing he can legally do with the results of the
cast is to cast them back to the original type. A compiler is
required to accept his code; although it can warn about it (a
compiler can warn about anything), reinterpret_cast is
traditionally a way of saying that I really, really know what
I'm doing (obviously not the case here), and shutting up all
warnings.

At run-time, of course, his use of the results of the
reinterpret_cast are undefined behavior, and I can't think of a
compiler where they'd actually work.
 
J

James Kanze

You can use union:
class Obj
{
public:
void Run()
{
this->*(pO[0].runA)();
this->*(pO[1].runB)();

That shouldn't compile, given the union you defined below; this
isn't the right type. (It's also lacking some parentheses.)
private:
A a;
B b;
union To
{
void A::*runA();
void B::*runB();
};
static To const pO[2];
};
// not sure about initialisation - perhaps only possible in C99
Obj::To const Obj::pO[2] =
{
{&A::Run},
{&B::Run}
};

You could use assignment somewhere, e.g. in an if in the
constructor. But once you've gotten the correct types in the
array, you have to call the function with the correct type; the
whole point of his exercise was to lie to the compiler, in order
to ensure that it generated incorrect code (and probably to use
some exotic and generally slow technique, like pointers to
members, rather than the usual faster technique of virtual
functions).
 
I

Immortal Nephi

Immortal Nephi wrote:
   I thought that you might find an interesting code.  Perhaps, you have
seen this before.  I created two classes of A and B.  Two classes have
different objects.  The class Obj has a relationship to class A and
class B which is called composition.
   The class Obj has one variable which is a pointer to member function
in array.  You can't bind member function of both class A and class B
because they do not belong to class Obj.  I use reinterpret_cast to
convert from class A to class Obj before pointer to member function is
invoked.
   I believe that my code is the alternative replacement so I don't use
inheritance and polymorphism.  It is easier to extract class.  What do
you think?
Your code has undefined behaviour, not to mention that the
compiler that is supposed to compile your
'reinterpret_cast' will exhibit undefined behaviour (most
likely).  Aside from that, you're good...
How did you say undefined behavior?  I played with
debugging.  I found out that reinterpret_cast array did
assign memory address correctly, but *this* pointer in class
A and class B assigns to the wrong memory address.
For example:
class ....
{
int a;
int b;
int c;
}
*this* pointer should always assigns to data member as a,
but it did assigns to either data member as b or c.  The
data was misplaced from a to b like memory misalignment.
I guess there is no alternative replacement to undefined
reinterpret_cast array, but switch block is the answer to each class'
member function.
Do you know if there is another way?  What about template array?
You can use union:
class Obj
{
public:
        void Run()
        {
                this->*(pO[0].runA)();
                this->*(pO[1].runB)();

That shouldn't compile, given the union you defined below; this
isn't the right type.  (It's also lacking some parentheses.)




        }
private:
        A a;
        B b;
        union To
        {
          void A::*runA();
          void B::*runB();
        };
        static To const pO[2];
};
// not sure about initialisation - perhaps only possible in C99
Obj::To const Obj::pO[2] =
{
        {&A::Run},
        {&B::Run}
};

You could use assignment somewhere, e.g. in an if in the
constructor.  But once you've gotten the correct types in the
array, you have to call the function with the correct type; the
whole point of his exercise was to lie to the compiler, in order
to ensure that it generated incorrect code (and probably to use
some exotic and generally slow technique, like pointers to
members, rather than the usual faster technique of virtual
functions).

James Kanze,

Hi, James. He is correct to point that Michael's post about union is
not working and C++ Compiler does not compile.

My question is always unanswered when I did research to find out
pointer to member function array.

Why member function pointer is **rarely** used in any C++ class? The
optimization speed shows the result here below.

C style code--

Example 1:

switch (...)
{
case 0x00:
func00();
case 0x01:
func01();
....
....
case 0xFF:
funcFF();
};

All global functions in the switch block is fair speed.

Example 2:

void func00();
void func01(),
....
....
void funcFF();

void (*pfn)() = { func00, func01, ..., ..., funcFF };

All global functions are stored in pointer to global function array is
faster than example 1 above because the code reads indirection once
before accesses memory address directly.


C++ style code--

Example 3:

class foo
{
void func00() {}
void func01() {}
....
....
void funcFF() {}
void ( *foo::*pfn[ 0x100 ] )();
};

Example 4:

class foo
{
void func00() {}
void func01() {}
....
....
void funcFF() {}
static void ( *foo::*pfn[ 0x100 ] )();
};

You can see non-static pointer to member function array in example 3
and static pointer to member function array in example 4.

Example 4 is faster than example 3 because example 4 is identical to
example 2 and static is declared.


Example 5:

class subFoo00 {};
class subFoo01 {};
....
....
class subFooFF {};

class foo
{
subFoo1 sf00;
subFoo2 sf01;
....
....
subFooFF sfFF;

void run()
{
switch (...)
{
case 0x00:
sf00.func00();
....
case 0x01:
sf01.func01();
....
....
case 0xFF:
sfFF.funcFF();
};
};
};

Do you see my point in example 5? class foo has a relationship to all
256 classes of subFoo00, subFoo01, ..., subFooFF. I extract from one
big class into 256 subclasses. All 256 subclasses are the alternative
replacement to inheritance and polymorphism.

Compare example 1 and example 5. I am unable to tell the speed
measurement because both example 1 and example 5 are very close.

Back to James Kanze' note --
You could use assignment somewhere, e.g. in an if in the
constructor. But once you've gotten the correct types in the
array, you have to call the function with the correct type; >the whole point of his exercise was to lie to the compiler,
in >order to ensure that it generated incorrect code (and
probably to use some exotic and generally slow technique,
like pointers to members, rather than the usual faster
technique of virtual functions).

How do you say *the usual faster technique of virtual function*?
class foo is the base class. All 256 classes are derived from base
class foo. They do not have composition. They enable to use
inheritance and polyporphism.

The virtual function has indirection overhead because it uses
indirection twice every time virtual function is invoked.

I need to decide whatever I want to choose either example 4 or example
5 or I have to use inheritance and polymorphism.

In the end of my writing. Why pointer to member function is rarely
used?

Thanks for being patience. Smile...
 
B

Balog Pal

"Immortal Nephi" <[email protected]>

Example 1:
switch (...)
{
case 0x00:
func00();
case 0x01:
func01();
....
....
case 0xFF:
funcFF();
};
All global functions in the switch block is fair speed.

Example 2:

void func00();
void func01(),
....
....
void funcFF();

void (*pfn)() = { func00, func01, ..., ..., funcFF };
All global functions are stored in pointer to global function array is
faster than example 1 above because the code reads indirection once
before accesses memory address directly.


Did you actually try it in practice? Or look at the code generated? IMO a
healthy optimizer would create the same code for your example#1 behind the
scenes. So they would run equally fast. Assuming you meant break after each
call of course.
 
I

Immortal Nephi

"Immortal Nephi" <[email protected]>

<quote>>Example 1:

switch (...)
{
case 0x00:
func00();
case 0x01:
func01();
...
...
case 0xFF:
funcFF();

};

Example 2:

void func00();
void func01(),
...
...
void funcFF();

void (*pfn)() = { func00, func01, ..., ..., funcFF };


Did you actually try it in practice? Or look at the code generated?  IMO a
healthy optimizer would create the same code for your example#1 behind the
scenes. So they would run equally fast.  Assuming you meant break after each
call of course.

Well, I am trying to say. Should I use what I want to write my code?
I always want to use C++ class. My either example 3 and example 4 are
preferred.

I am asking a question. ""Why member function pointer is **rarely**
used in any C++ class?""
 
B

Balog Pal

Immortal Nephi said:
I am asking a question. ""Why member function pointer is **rarely**
used in any C++ class?""

1. Because you quite rarely hase use cases where it is needed.
2. The few situations where it is good and used are probably wrapped in some
template so it is not apparent. (callbacks, bind ...)

And of course they are more rare than usual function pointers. You use tha
latter one to execute massively different things. Those are not likely
implemented in the same class.

And PTM makes sense when you want to select from functions of the same
class.

Class design normally aims as few functions as possible.

And dynamic dispatch is indeed easier done through virtuals -- or the
if/switch, if the number of conditions is small and bound.
 
I

Immortal Nephi

1. Because you quite rarely hase use cases where it is needed.
2. The few situations where it is good and used are probably wrapped in some
template so it is not apparent. (callbacks, bind ...)

And of course they are more rare than usual function pointers.  You use tha
latter one to execute massively different things.  Those are not likely
implemented in the same class.

And PTM makes sense when you want to select from functions of the same
class.

Class design normally aims as few functions as possible.

And dynamic dispatch is indeed easier done through virtuals -- or the
if/switch, if the number of conditions is small and bound.

Thank you for the answer. It makes sense. If one class contains 200,
400, or 1,000 private member functions, then I can choose either
pointer to member function array or one big switch block or outer
switch block and inner sub-switch block.

My code is ideal to use compile-time dispatch. Are you sure? If you
recommend me to create 200, 400, or 1,000 subclasses with one virtual
member function before I enable to use compile-time polymorphism
dispatch or dynamic polymorphism dispatch.
 
J

James Kanze

Immortal Nephi wrote:
I thought that you might find an interesting code. Perhaps, you have
seen this before. I created two classes of A and B. Two classes have
different objects. The class Obj has a relationship to class A and
class B which is called composition.
The class Obj has one variable which is a pointer to member function
in array. You can't bind member function of both class A and class B
because they do not belong to class Obj. I use reinterpret_cast to
convert from class A to class Obj before pointer to member function is
invoked.
I believe that my code is the alternative replacement so I don't use
inheritance and polymorphism. It is easier to extract class. What do
you think?
Your code has undefined behaviour, not to mention that the
compiler that is supposed to compile your
'reinterpret_cast' will exhibit undefined behaviour (most
likely). Aside from that, you're good...
How did you say undefined behavior? I played with
debugging. I found out that reinterpret_cast array did
assign memory address correctly, but *this* pointer in class
A and class B assigns to the wrong memory address.
For example:
class ....
{
int a;
int b;
int c;
}
*this* pointer should always assigns to data member as a,
but it did assigns to either data member as b or c. The
data was misplaced from a to b like memory misalignment.
I guess there is no alternative replacement to undefined
reinterpret_cast array, but switch block is the answer to each class'
member function.
Do you know if there is another way? What about template array?
You can use union:
class Obj
{
public:
void Run()
{
this->*(pO[0].runA)();
this->*(pO[1].runB)();
That shouldn't compile, given the union you defined below; this
isn't the right type. (It's also lacking some parentheses.)
}
private:
A a;
B b;
union To
{
void A::*runA();
void B::*runB();
};
static To const pO[2];
};
// not sure about initialisation - perhaps only possible in C99
Obj::To const Obj::pO[2] =
{
{&A::Run},
{&B::Run}
};
You could use assignment somewhere, e.g. in an if in the
constructor. But once you've gotten the correct types in the
array, you have to call the function with the correct type; the
whole point of his exercise was to lie to the compiler, in order
to ensure that it generated incorrect code (and probably to use
some exotic and generally slow technique, like pointers to
members, rather than the usual faster technique of virtual
functions).
He is correct to point that Michael's post about union is not
working and C++ Compiler does not compile.
My question is always unanswered when I did research to find
out pointer to member function array.
Why member function pointer is **rarely** used in any C++
class?

Mainly because it has an awkward syntax, and generally, there
are other solutions which result in easier to maintain code.

Note too that you need special options in order for pointer to
member functions to work correctly with some C++ compilers
(VC++, for example).

[...]
Compare example 1 and example 5. I am unable to tell the speed
measurement because both example 1 and example 5 are very close.

In general, the speed won't make a difference. Don't worry
about it; get the code working and maintainable first, then
worry about speed (at least at this level).
Back to James Kanze' note --
How do you say *the usual faster technique of virtual
function*? class foo is the base class. All 256 classes are
derived from base class foo. They do not have composition.
They enable to use inheritance and polyporphism.
The virtual function has indirection overhead because it uses
indirection twice every time virtual function is invoked.

Maybe. A pointer to member funtion involves several
indirections as well. Generally more than a virtual function
(but implementations vary).
I need to decide whatever I want to choose either example 4 or
example 5 or I have to use inheritance and polymorphism.
In the end of my writing. Why pointer to member function is rarely
used?

As I said above, they're rather awkward to use, and like
pointers to functions, can quickly lead to unmaintainable code.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top