Derived function chainging problem

I'm having a design problem that maybe someone here can help me with. It's pretty tricky, but kind of fun.

- I want a class which has a bunch of properties (A)
- I want a class which makes use of these properties (B)
- I want to pass temp B objects to functions where they can be applied
- I want to seperate A from B so that the properties can be stored seperately, and easily applied to multiple B objects, so that multiple B objects with all the same properties can be quickly created without having to reset all the properties over and over (but copying full B objects is not desired)
- I don't want the programmer to have to create an actual instance of a B object -- I would really prefer it if temp objects could always be used.

My idea was to derive B from A so that I can have A objects seperate from B objects, but have B inherit all the property functions from A. However this doesn't work so well with function chainging, I found. Here's my situation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 
// class A is the parent, it will have tons of "chained" functions
//   which return a reference to itself
class A
{
public:
    A& a() { return *this; }  // like this
};
 
// class B is a child that inherits all those chained functions
class B : public A
{
};
 
// this is so I can do stuff like:
B().a().a();
 
//as a shortcut to:
B b;
b.a();
b.a();
 
// the ultimate goal is to pass this as a temp object to another function:
 
void func_a(const A&);
void func_b(const B&);  // this is the function I want
 
//////////
 
func_b( B() );         // works because return is of type B
func_b( B().a().a() ); // fails because a() returns type A& not type B&
func_a( B().a().a() ); // works, but is kind of useless without an internal
                       //   dynamic_cast (blech)

B b;
b.a().a();
func_b(b);    //  works, but is not preferable 


The only solution to this problem I can see is to override all the property functions in B so that they return B&, but this kind of defeats the point of inheriting from A -- plus is extremely messy and would require a lot of additional code. I'm estimating about 25 or so of these property functions at least.

If this requires A to be aware of B, that's fine -- I don't have any problem with that... these two classes will be very closely linked. The only reason they're seperated is to make multiple object creation easier.

Any ideas on how else I could approach this? Do I just have to settle for a less than perfect scenario?

Any input welcome and appreciated
Thanks in advance.
You can overload an operator to convert an A into a B&

Eg:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class B;

class A
{
public:
    //...
    operator B& ();
};

class B : public A
{
   //...
};

A::operator B&()
{
    return dynamic_cast<B&>(*this);
}
Last edited on
1
2
3
4
5
6
template< typename Derived >
class A {
    Derived& a() { return *this; }
};

func_b( A<B>().a().a() );


?

Curiously Recurring Template Pattern
Topic archived. No new replies allowed.