Static Members and Inheritance

C

cppaddict

Hi,

Say I have a abstract base class and I know that every derived class
will have a static data member (call it SharedInformation)
representing information to be shared across all instances of that
derived class. However, this information will be differenet for each
derived class.

Now, if I define SharedInformation as a static member of the base
class, then SharedInformation cannot vary across the different derived
classes, because all derived classes will pointing to the same static
instance of SharedInformation. However, if I don't define it in the
base class, then someone looking at the base class won't know that
every derived class must define a static data member
SharedInformation.

How can I solve this problem? That is, have my base say, "All derived
classes will have a static data member called SharedInformation" but
still be able to have different static instances of SharedInformation
for each base class.

I know I may be looking at this problem in the wrong light. If so,
I'd appreciate any suggestions on how to re-conceptualize it.

thanks,
cpp
 
D

Dave Townsend

CPP,

Right now, I think your problem statement is a bit too vague
to offer a solution. I can think of several approaches based upon
some programming patterns used in MS Windows programming:

1. Use a class factory to create your objects, the factory effectively
provides
the "anchor" point to connect all instances of a manufactured class

2. Provide macros which generates a member function/data definition
to insert in the header/implementation of the class, something akin to
the macros used to support serialization of objects in MSVC++/MFC.

3. Implement the class using "policy" classes, that is a templatized
multiple
inheritance approach, weave in a special class which handles the static
registration of the derived class. This will require the "deriver" of
your
class to do so in the same way, which might or might not be acceptable.

I could go on, but it might be fruitless if I don't understand the context
of the
problem.

dave
 
C

cppaddict

I could go on, but it might be fruitless if I don't understand the context
of the
problem.

dave

Dave,

I'll try to give you a simple example. Say my base class is called
Document. It has methods like getLineNumber(int), appendLine(string),
etc. Perhaps I will have derived classes like Letter, ResearchPaper,
Article, etc.

Now let's say that every document must be written using a certain
Charset (a set of characters). Let's further assume that the Charset
is always the same for different instances of a specific derived class
(eg, all Letter instances use the same Charset), but that Charset is
not necessarily the same for different derived classes (eg, an Article
could use a different Charset from a Letter).

This suggests to me that:

1. Charset should be a static member of each derived class

2. The Document class should somehow state that all derived classes
must have a Charset.

Unfortunately you can't make Charset a static member of Document,
because that would force all derived classes of Document to use the
same Charset.

Does that make sense?

Thanks for any additional suggestions,
cpp
 
J

JKop

Using your method:


class VehicleClass
{



};


class CarClass : public VehicleClass
{



};

class MotorcycleClass : public VehicleClass
{


};



Let's say that the SharedInformation for CarClass is the year in which
Henry Ford was born, let's say it's 1902.
And let's say that the SharedInformation for MotorcycleClass is the
average length of the forks on a motorcycle, let's say it's 120. Here we go:


class VehicleClass
{
public:
unsigned long int* pSharedInformation;

}

class CarClass : public VehicleClass
{
private:
static unsigned long int SharedInformation;

public:
CarClass(void)
{
pSharedInformation = &SharedInformation;
}
};

class MotorcycleClass : public VehicleClass
{
private:
static unsigned long int SharedInformation;

public:
MotorcycleClass(void)
{
pSharedInformation = &SharedInformation;
}
};

unsigned long int CarClass::SharedInformation = 1902;

unsigned long int MotorcycleClass::SharedInformation = 120;


void ServiceVehicle(VehicleClass*);

int main(void)
{
CarClass Beamer;

MotorcycleClass Harley;


ServiceVehicle(&Beamer);
ServiceVehicle(&Harley);
}


void ServiceVehicle(VehicleClass* pVehicle)
{
cout << pVehicle->*pSharedInformation;

//Yes, I'm aware that I haven't include the
//appropriate header files!

//The above will yield 1902 for a car, and 120 for a
//motorcycle
}



That's one way of doing it. Obviously polymorphic functions with a return
type of unsigned long int would also work, they would also be easier. But
then I have my motto, easier isn't always better, take manual transmission
cars!!


Hope that helps.


-JKop
 
J

JKop

const unsigned long int* pSharedInformation;


const unsigned long int CarClass::SharedInformation = 1902;


const unsigned long int MotorcycleClass::SharedInformation = 120;



I tend to write code for myself, not others, so I seldom use "const". If
you're really paranoid about someone changing the value of the variable
pShareInformation in the base class, then make pSharedInformation private
and then stick this function into the base class:


unsigned long int GetSharedInformation(void)
{
return *pShareInformation;
}


What strikes me, and probably everyone else reading this, is that you could
do away with those variables altogether and just create a polymorphic
function called GetSharedInformation and then just define it in CarClass
and in MotorcycleClass. That's another possible method, one which *I* would
probably choose. Then again, there would be the disadvantage that you
wouldn't be able to edit the value of the variable. Maybe that's a good
thing, or then again maybe you *do* want to be able to, in which case you
can use my original example, or, alternatively, you could write another
polymorphic function called SetSharedInformation .

The possibilities are endless-ish!


-JKop
 
C

cppaddict

What strikes me, and probably everyone else reading this, is that you could
do away with those variables altogether and just create a polymorphic
function called GetSharedInformation and then just define it in CarClass
and in MotorcycleClass.

Indeed, now that you've pointed it out, it strikes ME as well. I
think that is the best solution for my problem, though your pointer
method is a good trick to know anyway.

Thanks for all the help,
cpp
 
J

John Harrison

cppaddict said:
Dave,

I'll try to give you a simple example. Say my base class is called
Document. It has methods like getLineNumber(int), appendLine(string),
etc. Perhaps I will have derived classes like Letter, ResearchPaper,
Article, etc.

Now let's say that every document must be written using a certain
Charset (a set of characters). Let's further assume that the Charset
is always the same for different instances of a specific derived class
(eg, all Letter instances use the same Charset), but that Charset is
not necessarily the same for different derived classes (eg, an Article
could use a different Charset from a Letter).

This suggests to me that:

1. Charset should be a static member of each derived class

2. The Document class should somehow state that all derived classes
must have a Charset.

Unfortunately you can't make Charset a static member of Document,
because that would force all derived classes of Document to use the
same Charset.

Does that make sense?

Thanks for any additional suggestions,
cpp

You are trying to capture type information (Article uses char set 1, Letter
uses char set 2) in data. A better way is to use virtual functions. For
instance

class Document
{
public:
virtual const CharSet& get_char_set() const = 0;
};

class Article : public Document
{
public:
virtual const CharSet& get_char_set() const { return article_char_set; }
private:
static CharSet article_char_set;
};

class Letter : public Document
{
public:
virtual const CharSet& get_char_set() const { return letter_char_set; }
private:
static CharSet letter_char_set;
};

If later you decide that you want Letter objects to store their own
individual char sets (say) then you can easily make letter_char_set
non-static and nothing else need change.

john
 
C

cppaddict

If later you decide that you want Letter objects to store their own
individual char sets (say) then you can easily make letter_char_set
non-static and nothing else need change.

john

John,

Thank you for that. That is the solution I'm going to go with.

cpp
 
J

JKop

cppaddict posted:
Indeed, now that you've pointed it out, it strikes ME as well. I
think that is the best solution for my problem, though your pointer
method is a good trick to know anyway.

Thanks for all the help,
cpp

If I was ever a C++ teacher, or wrote a book teaching C++, and I got to the
point where I was teaching polymorphism, I would first just show them how to
do it "manually" using function pointers, as I did with my variable
pointers. Then I would say to them, "Guess what?! C++ has a built-in thing
that does this for you, it's called polymorphism, so now you don't have to
write a big bulge of code for EVERY class you write!". The result of this is
that the student would understand polymorphism perfectly and entirely!

When *I* first came to the chapter on polymorphism, I took one look at the
word and made sure I was sitting up straight and paying full attention to
the text, to try digest the whole thing. The name, "polymorphism", is
stupid, it's like something out of biology - it implies that the concept is
much more complicated and hard to comprehend than it actually is!, when in
essence it's just a nice pointer trick!

And you've got to love my polymorphism with member variables!


-JKop
 
J

jeffc

cppaddict said:
Hi,

Say I have a abstract base class and I know that every derived class
will have a static data member (call it SharedInformation)
representing information to be shared across all instances of that
derived class. However, this information will be differenet for each
derived class.

Now, if I define SharedInformation as a static member of the base
class, then SharedInformation cannot vary across the different derived
classes, because all derived classes will pointing to the same static
instance of SharedInformation. However, if I don't define it in the
base class, then someone looking at the base class won't know that
every derived class must define a static data member
SharedInformation.

How can I solve this problem? That is, have my base say, "All derived
classes will have a static data member called SharedInformation" but
still be able to have different static instances of SharedInformation
for each base class.

I don't think you need anything static. Simply have a function that returns
the value you want. Then override this function for any subclasses that
return a different value. You're asking for a "static" solution to a
"dynamic" problem. This is what OO is for.
 
J

jeffc

JKop said:
The result of this is
that the student would understand polymorphism perfectly and entirely!
Hmmm.

When *I* first came to the chapter on polymorphism, I took one look at the
word and made sure I was sitting up straight and paying full attention to
the text, to try digest the whole thing. The name, "polymorphism", is
stupid, it's like something out of biology - it implies that the concept is
much more complicated and hard to comprehend than it actually is!, when in
essence it's just a nice pointer trick!

Hmmm.
 

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,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top