How to build a better diamond?

  • Thread starter Steven T. Hatton
  • Start date
S

Steven T. Hatton

Below is some code I wrote to get a better understanding of the dynamic
verses static type resolution. My intention was to see if there was a way
to use references for the static access to the subobjects of an object of
derived type. I thought I had seen a way to use references to statically
access member functions in a way syntactically similar to how pointers
dynamically access the same objects member functions.

The overall objective is to 'navigate' the diamond in the most elegant and
safe way. I had hoped to use this as a follow up to the discussion on
references and pointers and other objects(sic). Unfortunately I wasn't able
to find a way to do what I thought I could.

Do othere people have comments on how best to 'navigate' the class
hierarchy?

#include <string>
#include<iostream>

using std::string;


class North
{
public:
North(const string& name="North"):m_name(name)
{}
virtual string& toString() { return m_name; }
private:
string m_name;
};

class East : virtual public North
{
public:
East(const string& name="East"):m_name(name)
{}
virtual string& toString()
{
string* ret = new string(North::toString());
*ret += "::";
*ret += m_name;
return *ret;
}
private:
string m_name;
};

class West : virtual public North
{
public:
West(const string& name="West"):m_name(name)
{}
virtual string& toString()
{
string* ret = new string(North::toString());
*ret += "::";
*ret += m_name;
return *ret;
}
private:
string m_name;
};

class South : public East, public West
{
public:
South(const string& name="South"):m_name(name)
{}
virtual string& toString()
{
string* ret = new string(East::toString());
*ret += "::";
*ret += West::toString();
*ret += "::";
*ret += m_name;
return *ret;
}
private:
string m_name;
};


int main()
{
using std::cout;
using std::endl;

North n;
East e;
West w;
South s;
cout<<n.toString()<<endl;
cout<<e.toString()<<endl;
cout<<w.toString()<<endl;
cout<<s.toString()<<endl;

North ns = static_cast<North>(s);
East es = static_cast<East>(s);
West ws = static_cast<West>(s);
cout<<ns.toString()<<endl;
cout<<es.toString()<<endl;
cout<<ws.toString()<<endl;
}

/*OUTPUT*/
North
North::East
North::West
North::East::North::West::South
North
North::East
North::West
 
A

Alf P. Steinbach

* "Steven T. Hatton said:
#include <string>
#include<iostream>

using std::string;


class North
{
public:
North(const string& name="North"):m_name(name)
{}
virtual string& toString() { return m_name; }

Ungood to return reference to internal member here, and should be const
function to allow calls on const object, thus:


virtual string toString() const { return m_name; }


Also, consider a private or protected function name() instead of member;
the function won't occupy storage per object.

private:
string m_name;
};

class East : virtual public North
{
public:
East(const string& name="East"):m_name(name)
{}
virtual string& toString()
{
string* ret = new string(North::toString());
*ret += "::";
*ret += m_name;
return *ret;
}

1) The code does not deallocate 'ret'.
2) It's not exception safe. For exception safe you'd have to use
std::auto_ptr. But
3) A better way is 'return North::toString() + "::" + m_name';

North::East::North::West::South

I suggest forgetting that diamond inheritance pattern for a while;
concentrate on just creating some useful program.
 
S

Steven T. Hatton

Alf said:
Ungood to return reference to internal member here,

Agreed. I wasn't sure how best to return a copy.
and should be const
function to allow calls on const object, thus:

I wasn't sure of the syntax. I tried a couple combination, but they didn't
compile. I really think I need to get the C++ Pocket Reference. It's hard
to find good paradigms in the materials I have at hand.
virtual string toString() const { return m_name; }

Thanks for the example.
Also, consider a private or protected function name() instead of member;
the function won't occupy storage per object.

I'm not exactly sure what you're suggesting. Is this related to
std::type_info?

1) The code does not deallocate 'ret'.

I was aware of that. This is one of the reasons Java's string is immutable.
It's also why Xerces C++ XMLstring class is such a monster. I guess the way
to address a situation like this is with handles. I didn't want to get
that deep into things just yet.
2) It's not exception safe. For exception safe you'd have to use
std::auto_ptr. But
3) A better way is 'return North::toString() + "::" + m_name';

I wasn't sure what that would do. I /believe/ it does about the same thing
as what I provided, but never creates an explicit pointer. I don't know
what scoping and lifetime rules apply. If it's allocated as dynamic
storage (which I believe it will be), the onus is on me to release it when
I'm finished.
I suggest forgetting that diamond inheritance pattern for a while;
concentrate on just creating some useful program.

The inheritance doesn't seem all that confusing in general. The thing I'm
really trying to get a handle on through this exercise is how references
and pointers work WRT overloaded (and hidden) virtual functions. I guess
that wasn't very obvious since all the code I posted used values rather
than pointers and references. I figure, if I can keep creating instructive
and interesting examples based on the pattern of the code I posted, it will
serve as a way to reinforce the trickier lessons surrounding inheritance.

As for writing useful programs, that's why I gave up on C++ last time. It
was too frustrating to know what I wanted to do, but not how to do it. I
had created the UI shown below with the data elements backed by
QDomElements. I tried creating another feature using templates and ended
up so tangled up I just quit.

http://baldur.globalsymmetry.com/gs-home/images/kgrammar.png
 

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,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top