Inheritance and Data Access Question

B

bogus1one

Let's say I have the following:

#include <iostream>

using namespace std;

class B
{
};

class D1 : public B
{
public:
// Header Functions are the Same
int Fh1() {return 1;}
int Fh2() {return 2;}
int Fh3() {return 3;}

// Body Functions are Unique
int Fba() {return 'a';}
int Fbb() {return 'b';}
int Fbc() {return 'c';}
};

class D2 : public B
{
public:
// Header Functions are the Same
int Fh1() {return 1;}
int Fh2() {return 2;}
int Fh3() {return 3;}

// Body Functions are Unique
int Fbx() {return 'x';}
int Fby() {return 'y';}
int Fbz() {return 'z';}
};

int ParseHeader()
{
// What should go here?
return 0;
}

int main(int argc, char* argv[])
{
D1 d1;
D2 d2;

// Parsing D1 Header
cout << "Parse D1 Header" << endl;
ParseHeader();

// Parsing D1 Body
cout << "D1 Fba = " << d1.Fba() << endl;
cout << "D1 Fbb = " << d1.Fbb() << endl;

// Parsing D2 Header
cout << "Parse D2 Header" << endl;
ParseHeader();

// Parsing D2 Body
cout << "D2 Fbx = " << d2.Fbx() << endl;
cout << "D2 Fby = " << d2.Fby() << endl;

return 0;
}

In the above, I can't modify anything in the classes D1 or D2 or B as
these classes are provided by a 3rd party tool.

The classes provide data binding for an XML messaging protocol. In
this protocol, the header for every message will have the same
structure. You will note above the header functions are the same
across the two classes Fh1(), Fh2() and Fh3().

What I would like to do is abstract out the functionality to retrieve
the header information from the messages as this will be the same
across all messages. In my example, I show this as the ParseHeader()
function. I'm looking for suggestions on the best way to accomplish
this. I tried something with multiple inheritance but I couldn't make
it work. It smells like there's an elegant way to accomplish this but
I just can't put my finger on it.

Thanks.
Dan
 
V

Victor Bazarov

Let's say I have the following:

#include <iostream>

using namespace std;

class B
{
};

class D1 : public B
{
public:
// Header Functions are the Same
int Fh1() {return 1;}
int Fh2() {return 2;}
int Fh3() {return 3;}

// Body Functions are Unique
int Fba() {return 'a';}
int Fbb() {return 'b';}
int Fbc() {return 'c';}
};

class D2 : public B
{
public:
// Header Functions are the Same
int Fh1() {return 1;}
int Fh2() {return 2;}
int Fh3() {return 3;}

// Body Functions are Unique
int Fbx() {return 'x';}
int Fby() {return 'y';}
int Fbz() {return 'z';}
};

int ParseHeader()
{
// What should go here?
return 0;
}

template<class D>
int ParseHeader(D& d)
{
cout << d.Fh1() << d.Fh2() << d.Fh3() << endl;
return 0;
}
int main(int argc, char* argv[])
{
D1 d1;
D2 d2;

// Parsing D1 Header
cout << "Parse D1 Header" << endl;
ParseHeader();

ParseHader(d1);
// Parsing D1 Body
cout << "D1 Fba = " << d1.Fba() << endl;
cout << "D1 Fbb = " << d1.Fbb() << endl;

// Parsing D2 Header
cout << "Parse D2 Header" << endl;
ParseHeader();

ParseHeader(d2);
// Parsing D2 Body
cout << "D2 Fbx = " << d2.Fbx() << endl;
cout << "D2 Fby = " << d2.Fby() << endl;

return 0;
}

In the above, I can't modify anything in the classes D1 or D2 or B as
these classes are provided by a 3rd party tool.

The classes provide data binding for an XML messaging protocol. In
this protocol, the header for every message will have the same
structure. You will note above the header functions are the same
across the two classes Fh1(), Fh2() and Fh3().

What I would like to do is abstract out the functionality to retrieve
the header information from the messages as this will be the same
across all messages. In my example, I show this as the ParseHeader()
function. I'm looking for suggestions on the best way to accomplish
this. I tried something with multiple inheritance but I couldn't make
it work. It smells like there's an elegant way to accomplish this but
I just can't put my finger on it.

Unless you need a true run-time polymorphism (which you didn't show),
the templates should work just fine.

V
 
D

Daniel T.

Let's say I have the following:
#include <iostream>
using namespace std;
class B
{
};
class D1 : public B
{
public:
// Header Functions are the Same
int Fh1() {return 1;}
int Fh2() {return 2;}
int Fh3() {return 3;}

// Body Functions are Unique
int Fba() {return 'a';}
int Fbb() {return 'b';}
int Fbc() {return 'c';}
};
class D2 : public B
{
public:
// Header Functions are the Same
int Fh1() {return 1;}
int Fh2() {return 2;}
int Fh3() {return 3;}

// Body Functions are Unique
int Fbx() {return 'x';}
int Fby() {return 'y';}
int Fbz() {return 'z';}
};

template said:
int ParseHeader( T& foo)
{

foo.Fh1();
foo.Fh2();
foo.Fh3();
return 0;
int main(int argc, char* argv[])
{
D1 d1;
D2 d2;

// Parsing D1 Header
cout << "Parse D1 Header" << endl;

ParseHeader( d1 );
// Parsing D1 Body
cout << "D1 Fba = " << d1.Fba() << endl;
cout << "D1 Fbb = " << d1.Fbb() << endl;

// Parsing D2 Header
cout << "Parse D2 Header" << endl;

ParseHeader( d2 );
// Parsing D2 Body
cout << "D2 Fbx = " << d2.Fbx() << endl;
cout << "D2 Fby = " << d2.Fby() << endl;
return 0;
}
In the above, I can't modify anything in the classes D1 or D2 or B as
these classes are provided by a 3rd party tool.
 
S

Salt_Peter

Let's say I have the following:

#include <iostream>

using namespace std;

class B
{
};

class D1 : public B
{
public:
// Header Functions are the Same
int Fh1() {return 1;}
int Fh2() {return 2;}
int Fh3() {return 3;}

all of these functions should be const.
ie:
int Fh1() const { return 1; }
// Body Functions are Unique
int Fba() {return 'a';}
int Fbb() {return 'b';}
int Fbc() {return 'c';}
};

class D2 : public B
{
public:
// Header Functions are the Same
int Fh1() {return 1;}
int Fh2() {return 2;}
int Fh3() {return 3;}

// Body Functions are Unique
int Fbx() {return 'x';}
int Fby() {return 'y';}
int Fbz() {return 'z';}
};

int ParseHeader()
{
// What should go here?
return 0;
}

int main(int argc, char* argv[])
{
D1 d1;
D2 d2;

// Parsing D1 Header
cout << "Parse D1 Header" << endl;
ParseHeader();

// Parsing D1 Body
cout << "D1 Fba = " << d1.Fba() << endl;
cout << "D1 Fbb = " << d1.Fbb() << endl;

// Parsing D2 Header
cout << "Parse D2 Header" << endl;
ParseHeader();

// Parsing D2 Body
cout << "D2 Fbx = " << d2.Fbx() << endl;
cout << "D2 Fby = " << d2.Fby() << endl;

return 0;
}

In the above, I can't modify anything in the classes D1 or D2 or B as
these classes are provided by a 3rd party tool.

The classes provide data binding for an XML messaging protocol. In
this protocol, the header for every message will have the same
structure. You will note above the header functions are the same
across the two classes Fh1(), Fh2() and Fh3().

What I would like to do is abstract out the functionality to retrieve
the header information from the messages as this will be the same
across all messages. In my example, I show this as the ParseHeader()
function. I'm looking for suggestions on the best way to accomplish
this. I tried something with multiple inheritance but I couldn't make
it work. It smells like there's an elegant way to accomplish this but
I just can't put my finger on it.

As it stands, ParseHeader() can only deal with either a D1 object, a D2
object or both simultaneously. It can't take a reference to B unless B
has virtual or pure virtual functions.
Dynamic casting is not an option since B has no virtual functions.
Instead of abstacting out, you'ld need to abstract in if you plan to
have ParseHeader accept either a D1 or a D2 object.

In your particular case, here is what i'ld do (which in effect does
modify D1 and D2 polymorphicly):

struct Base
{
~Base() { } // might need to be virtual
virtual int Fh1() = 0;
virtual int Fh2() = 0;
virtual int Fh3() = 0;
};

class MyD1 : public D1, public Base
{
int Fh1() { return D1::Fh1(); }
int Fh2() { return D1::Fh2(); }
int Fh3() { return D1::Fh3(); }
};

class MyD2 : public D2, public Base
{
int Fh1() { return D2::Fh1(); }
int Fh2() { return D2::Fh2(); }
int Fh3() { return D2::Fh3(); }
};

int ParseHeader(Base& r_b)
{
return r_b.Fh1(); // or whatever
}

int main()
{
MyD1 d1;
MyD2 d2;

// Parsing D1 Header
std::cout << "Parse D1 Header";
std::cout << ParseHeader(d1) << std::endl;

// Parsing D2 Header
std::cout << "Parse D2 Header" << std::endl;
std::cout << ParseHeader(d2) << std::endl;
}

If that doesn't fit the bill, ParseHeader() will need to be implemeted
twice. Unless, of couse, there is something about B you aren't telling
us about.
 
B

bogus1one

How incredibly simple! Thanks to all who replied.
Dan


Victor said:
Let's say I have the following:

#include <iostream>

using namespace std;

class B
{
};

class D1 : public B
{
public:
// Header Functions are the Same
int Fh1() {return 1;}
int Fh2() {return 2;}
int Fh3() {return 3;}

// Body Functions are Unique
int Fba() {return 'a';}
int Fbb() {return 'b';}
int Fbc() {return 'c';}
};

class D2 : public B
{
public:
// Header Functions are the Same
int Fh1() {return 1;}
int Fh2() {return 2;}
int Fh3() {return 3;}

// Body Functions are Unique
int Fbx() {return 'x';}
int Fby() {return 'y';}
int Fbz() {return 'z';}
};

int ParseHeader()
{
// What should go here?
return 0;
}

template<class D>
int ParseHeader(D& d)
{
cout << d.Fh1() << d.Fh2() << d.Fh3() << endl;
return 0;
}
int main(int argc, char* argv[])
{
D1 d1;
D2 d2;

// Parsing D1 Header
cout << "Parse D1 Header" << endl;
ParseHeader();
ParseHader(d1);


// Parsing D1 Body
cout << "D1 Fba = " << d1.Fba() << endl;
cout << "D1 Fbb = " << d1.Fbb() << endl;

// Parsing D2 Header
cout << "Parse D2 Header" << endl;
ParseHeader();
ParseHeader(d2);


// Parsing D2 Body
cout << "D2 Fbx = " << d2.Fbx() << endl;
cout << "D2 Fby = " << d2.Fby() << endl;

return 0;
}

In the above, I can't modify anything in the classes D1 or D2 or B as
these classes are provided by a 3rd party tool.

The classes provide data binding for an XML messaging protocol. In
this protocol, the header for every message will have the same
structure. You will note above the header functions are the same
across the two classes Fh1(), Fh2() and Fh3().

What I would like to do is abstract out the functionality to retrieve
the header information from the messages as this will be the same
across all messages. In my example, I show this as the ParseHeader()
function. I'm looking for suggestions on the best way to accomplish
this. I tried something with multiple inheritance but I couldn't make
it work. It smells like there's an elegant way to accomplish this but
I just can't put my finger on it.

Unless you need a true run-time polymorphism (which you didn't show),
the templates should work just fine.

V
 

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

Staff online

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,142
Latest member
DewittMill
Top