Reputation: 4752
So we have a class, Customer
. I don't have any choice but to use Customer
to represent any Customer I have, including in the signature of any methods, etc I write. But my data is slightly different; I still want much of the functionality inside Customer
, but some fields I need to sorta bastardize for my special case. Example:
class Customer
{
public:
string GetName();
void SetName(string _name);
string GetAge();
void SetAge(string _age);
protected:
string name;
string age;
};
class SpecialCustomer : public Customer
{
public:
string GetAddress();
void SetAddress(string _address);
}
So this all seems rather simple, but the problem I have is I am forced to pass around Customer
s. But as luck would have it, in my special case, I don't need age
at all! So what I need to do is re-use the age
data member to hold my address. Yes, I know it's bad. No, I can't change the requirements - my special data has to fit into a Customer
object.
So to do this, I could of course just construct a SpecialCustomer
from a Customer
, but I'd like to avoid the copy. (edit: Also, many data members are exposed directly publicly, so I can't use composition and support their use) Instead, I considered making SpecialCustomer
a wrapper, exposing the pieces of functionality I want. The problem is the real implementation of Customer
is not trivial - it's be a bit of work to re-implement the whole interface, minus the fields I don't want.
The only way that jumps to mind to achieve this is with something like this:
void foo (Customer & _c)
{
SpecialCustomer & sc = reinterpret_cast<SpecialCustomer &>(_c);
}
Obviously if SpecialCustomer
has any virtual methods or data members, this won't work. But what if it is just a set of methods I want available on the object? Is there a better alternative to achieve this functionality?
Upvotes: 1
Views: 94
Reputation: 57
Seems like your hands are tied from using OO techniques. How about using plain old non-member functions of the form
string getSpecialCustomerAddress (Customer & _c)
{
return _c.GetAge();
}
You still have the problem of determining whether or not a customer is special
Upvotes: 1
Reputation: 4810
This ought to do it, using composition instead of inheritance.
class SpecialCustomer {
public:
SpecialCustomer(Customer&) : _customer(customer) {}
string getAge() { return customer.GetAge(); }
private:
Customer& _customer;
}
No casting is needed at this point. Rather instantiating the wrapper class will be adequate.
Usage:
void foo (Customer & _c)
{
SpecialCustomer sc(_c);
}
Upvotes: 0