Connecting Tech Pros Worldwide Help | Site Map

oo design question

Joseph Y. Oh
Guest
 
Posts: n/a
#1: Jun 27 '08
Hello,

class A {
public:
A& operator+=( const A& a ) = 0;
};

class B1:public A {
public:
A& operator+=( const A& a ) { ... }
};

class B2:public A {
public:
A& operator+=( const A& a ) { ... }
};

class C {

public:
void Move(double t) { (*_a1) += (*_a2)*t; }
private:
A* _a1;
A* _a2;
};

For Move(), I have to define the operator +=() and *().
Unlike operator+=(), operator*() must be defined as friend:
For example, for B1,
friend B1 operator*( const B1&, double);
friend B1 operator*( double, const B1&);

But class C cannot access the above operator.
Is there any way to access the operator* of B1 and B2 from C?

Thanks,
Joseph.




Christian Hackl
Guest
 
Posts: n/a
#2: Jun 27 '08

re: oo design question


Joseph Y. Oh wrote:
Quote:
class A {
public:
A& operator+=( const A& a ) = 0;
};
>
class B1:public A {
public:
A& operator+=( const A& a ) { ... }
};
>
class B2:public A {
public:
A& operator+=( const A& a ) { ... }
};
>
class C {
>
public:
void Move(double t) { (*_a1) += (*_a2)*t; }
private:
A* _a1;
A* _a2;
};
>
For Move(), I have to define the operator +=() and *().
Unlike operator+=(), operator*() must be defined as friend:
For example, for B1,
friend B1 operator*( const B1&, double);
friend B1 operator*( double, const B1&);
>
But class C cannot access the above operator.
Is there any way to access the operator* of B1 and B2 from C?
If I understand correctly, you need a "virtual friend" function. While
that mechanism is not directly supported by the language, you can easily
simulate it. Give A a friend operator* that calls a private virtual
function on an A argument. B1 and B2 override the private virtual function.

The general technique is described here:
http://www.parashift.com/c++-faq-lit...html#faq-15.11

However, in this case I think you should consider not overloading
operator* and use an ordinary member function instead. The signature of
operator* should be made so that it returns an A const. But that's not
possibile because A is an abstract class, so you cannot create instances
of it. You would have to use a return type other than what the user of
the class probably expects (for example, an A*), thereby making your
class harder to use, defeating the purpose of operator overloading.


--
Christian Hackl
Joseph Y. Oh
Guest
 
Posts: n/a
#3: Jun 27 '08

re: oo design question


Thanks for your answer.
Sounds like what I want is not possible...
Daniel T.
Guest
 
Posts: n/a
#4: Jun 27 '08

re: oo design question


"Joseph Y. Oh" <josephyoungoh@yahoo.comwrote:
Quote:
Thanks for your answer.
Sounds like what I want is not possible...
It's not that it is not possible, it's not logical.

Let's look at the code again:

class A {
public:
virtual ~A() = 0;
};

A::~A() { }

const ? operator*( const A& left, const B& right );

Note the question mark above, what type could possibly be placed there
and have it make any sense at all?
Joseph Y. Oh
Guest
 
Posts: n/a
#5: Jun 27 '08

re: oo design question


Maybe my explanation was not clear enough.
Let me describe again what I want to do.

There are 4 classes, P, A, B1 and B2.

class P;
class A;
class B1;
class B2;

P "has a" A pointer.
B1 and B2 "is a" A. (i.e. B1 and B2 are the derived classes from A)


class P
{
public:
P( bool b );
void update(double t);
private:
A* _a1P;
A* _a2P;
};

Here it is assumed that (*_a1P) and (*_a2P) are the same class objects
e.g. if _a1P is the pointer of B1, then _a2P too.

P::P( bool b )
{
if( b )
{
_a1P = new B1();
_a2P = new B1();
}
else
{
_a1P = new B2();
_a2P = new B2();
}
}

void P::update(double t)
{
A& a1 = *_a1P;
A& a2 = *_a2P;

a1 += a2 * t;
}

How can you do "a1 += a2 * t" by operator overloading ?
operator+=() is easy because the returned value is not object
but reference. However, operator*() is not because it requires
copied object.
That's the reason why I posted this question here.
Do you think that this still doesn't make sense?


On Sun, 18 May 2008 10:20:51 -0400, Daniel T. wrote:
Quote:
"Joseph Y. Oh" <josephyoungoh@yahoo.comwrote:
>
Quote:
>Thanks for your answer.
>Sounds like what I want is not possible...
>
It's not that it is not possible, it's not logical.
>
Let's look at the code again:
>
class A {
public:
virtual ~A() = 0;
};
>
A::~A() { }
>
const ? operator*( const A& left, const B& right );
>
Note the question mark above, what type could possibly be placed there
and have it make any sense at all?
Daniel T.
Guest
 
Posts: n/a
#6: Jun 27 '08

re: oo design question


"Joseph Y. Oh" <josephyoungoh@yahoo.comwrote:
Quote:
Maybe my explanation was not clear enough.
Let me describe again what I want to do.
>
There are 4 classes, P, A, B1 and B2.
>
class P;
class A;
class B1;
class B2;
>
P "has a" A pointer.
B1 and B2 "is a" A. (i.e. B1 and B2 are the derived classes from A)
>
>
class P
{
public:
P( bool b );
void update(double t);
private:
A* _a1P;
A* _a2P;
};
>
Here it is assumed that (*_a1P) and (*_a2P) are the same class objects
e.g. if _a1P is the pointer of B1, then _a2P too.
Here is your problem. Don't assume, express it in the code directly.

template < typename T >
class P
{
public:
P(); // no bool argument necessary
void update( double t );
private:
T* _a1P;
T* _a2P;
};

With the above, and properly defined functions, you can do the multiply.
Closed Thread