how to static_cast<MyClass* &>(p) ???

W

Wenjie

Hello,


I have a class B to mediate/isolate between
implementation and their users (like used in
an abstract factory class pattern):
// B.h
class B {
static B* getImpl();
static void update(B*& previous, B*& current);
};

// I.h
class I: public B {
static I* instance();
static void update(I*& previous, I*& current);
};

// B.cpp
B* B::getImpl()
{
return I::instance();
}

void B::update(B*& previous, B*& current)
{
return I::update((I*&)previous, (I*&)current);
}

I try to use static_cast<I*&>(previous) for (I*&) previous
but failed to compile for the above member function.

Do you think static_cast<I*>(previous) is OK for the cast?

Secondly, do you have a better pattern to achieve the
isolation as well as the task routing?


Thanks and best regards!
Wenjie
 
G

Gianni Mariani

Wenjie said:
Hello,


I have a class B to mediate/isolate between
implementation and their users (like used in
an abstract factory class pattern):
// B.h
class B {
static B* getImpl();
static void update(B*& previous, B*& current);
};

// I.h
class I: public B {
static I* instance();
static void update(I*& previous, I*& current);
};

// B.cpp
B* B::getImpl()
{
return I::instance();
}

void B::update(B*& previous, B*& current)
{
return I::update((I*&)previous, (I*&)current);
}

I try to use static_cast<I*&>(previous) for (I*&) previous
but failed to compile for the above member function.

Do you think static_cast<I*>(previous) is OK for the cast?

Let's re-write this a little.

void B::update(B*& previous, B*& current)
{
I * l_prev = previous; // down cast - bad news
I * l_curr = current; // down cast - bad news

I::update( l_prev, l_curr );

previous = l_prev; // up casting OK
current = l_curr; // up casting OK
}

Basically, your original version is using a B* pointer and saying it's
really an I* pointer. VERY dangerous. You can convert pointers
Secondly, do you have a better pattern to achieve the
isolation as well as the task routing?

What are you really trying to do ?

One suggestion:

class I: public B {

// Create this method instead.

static void update(B*& previous, B*& current);
 
V

Victor Bazarov

Wenjie said:
I have a class B to mediate/isolate between
implementation and their users (like used in
an abstract factory class pattern):
// B.h
class B {
static B* getImpl();
static void update(B*& previous, B*& current);
};

// I.h
class I: public B {
static I* instance();
static void update(I*& previous, I*& current);
};

// B.cpp
B* B::getImpl()
{
return I::instance();
}

void B::update(B*& previous, B*& current)
{
return I::update((I*&)previous, (I*&)current);
}

I try to use static_cast<I*&>(previous) for (I*&) previous
but failed to compile for the above member function.

B* and I* are unrelated types. A reference to one cannot be
converted to a reference to the other. Why do you need those
references to pointers anyway? Can't you just have B& or B*?
They would be convertable to I& or I* using static_cast.
Do you think static_cast<I*>(previous) is OK for the cast?

I think your design is utterly flawed. "B" should not know
that there exists "I" who derives from it. Making the base
class aware of any derived classes is against all applicable
principles of OOP.

Having said that, I think you should employ polymorphism here.
What does 'update' function do? Can it be converted to become
a member? Example:

class B {
virtual void update_(B* current) {} // default - nothing
public:
static void update(B* previous, B* current);
};

class I : public B {
void update_(B* current); // real 'I' implementation of
// update functionality -- hidden
};

void B::update(B* previous, B* current) {
previous->update_(current); // virtual call
}

Of course, 'update_' can try converting 'current' into 'I*'
if it needs to, using static_cast or, better yet, dynamic_cast.
And it could call any local static function if necessary.
Secondly, do you have a better pattern to achieve the
isolation as well as the task routing?

I don't. Try the book of patterns.

Victor
 
W

Wenjie

Victor Bazarov said:
B* and I* are unrelated types. A reference to one cannot be
converted to a reference to the other. Why do you need those
references to pointers anyway? Can't you just have B& or B*?
They would be convertable to I& or I* using static_cast.

Doesn't "I" inherited from "B"? I maintain a linked list of
"I" in "I" but with the 'interface' of "B". The reference is
to let the call update() to update the pointers of the calling
block, which is a hash table in user codes block with those
linked lists. I did try B* but failed (I will examine the
exact difficulty later).
 
V

Victor Bazarov

Wenjie said:
Doesn't "I" inherited from "B"? I maintain a linked list of
"I" in "I" but with the 'interface' of "B". The reference is
to let the call update() to update the pointers of the calling
block, which is a hash table in user codes block with those
linked lists. I did try B* but failed (I will examine the
exact difficulty later).

"I" inherits from "B". But "I*" does not inherit from "B*".

With the existing relationship between I and B conversions
work: from I& to B& (implicitly), from I* to B* (implicitly),
from B& to I& (explicitly, use 'static_cast'), from B* to I*
(explicitly, use 'static_cast'). But no other conversions
exist.

struct B {};
struct I : B {};

int foo(B*) { return 1; }
int boo(B&) { return 2; }
int bar(B*&) { return 3; }

int main() {
I i;
foo(&i); // fine. I* to B* conversion
boo(i); // fine. I& to B& conversion
I *pi = &i;
bar(pi); // error. Cannot initialise B*& with I*
}

Victor
 

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,763
Messages
2,569,562
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top