virtual base classes, templates, and static functions

C

cmonthenet

Hello,
I searched for an answer to my question and found similar posts,
but none that quite addressed the issue I am trying to resolve.
Essentially, it seems like I need something like a virtual static
function (which I know is illegal), but, is there a way to provide
something similar? The class that is the target of my inquiry is a
template class that interfaces to one of several derived classes
through a pointer to a base class. The specific derived class that is
interfaced to depends on the template parameter provided. However, in
a few cases, I need to call a static (class) function associated with
the derived class when an objects of that class may not exist. Two
possibilities I have come up with are to 1) pass the static function
of the dervied class to the target class as a callback function or 2)
add the interface to the abstract base class, remove the static
designation of the function in the derived class, and use a half-
initialized object (ughh!) to access the function through a pointer to
the base class. Is there a better, more elegant way to do this?

Thanks,
Carl

Code example below.


template <typename T>
class Base
{
public:
// illegal to declare a virtual static function here
virtual void func1(T& a) = 0;
virtual void func2(T& b) = 0;
// ...
};

class Derived1 : public Base<int>
{
public:
static void Derived1Func(int& x); // type T is int in this case
void func1(int& a);
void func2(int& b);
// ...
};

class XyzType
{
XyzType() {}
~XyzType() {}
};

class Derived2 : public Base<XyzType>
{
public:
static void Derived2Func(XyzType& x); // type T is XyzType here
void func1(int& a);
void func2(int& b);
// ...
};

template <typename T>
class Target
{
void aFunc(Base<T> *ptr);
void bFunc(Base<T> *ptr);
// ...
};

template <typename T>
void Target<T>::aFunc(Base<T> *ptr)
{
T aT;

ptr->func1(T& aT); // great, works fine
};

template <typename T>
void Target<T>::bFunc(Base<T> *ptr)
{

// now here I need to get a handle on Derived1Func or Derived2Func
// ... or DerivedNFunc depending on the T parameter, or some other
parameter
// if necessary. But I cannot call any of them directly because this
class
// primarily uses an interface to reference the specific derived
class
// (and does not know or care which derived class it is)


};
 
V

Victor Bazarov

Hello,
I searched for an answer to my question and found similar posts,
but none that quite addressed the issue I am trying to resolve.
Essentially, it seems like I need something like a virtual static
function (which I know is illegal), but, is there a way to provide
something similar? The class that is the target of my inquiry is a
template class that interfaces to one of several derived classes
through a pointer to a base class.

That's what's happening, but it doesn't seem to be the design intent.
It interfaces with the base class object via a pointer to it. Whoever
is hiding behind that pointer should be immaterial to your "target"
class, if everything is designed correctly.
The specific derived class that is
interfaced to depends on the template parameter provided. However, in
a few cases, I need to call a static (class) function associated with
the derived class when an objects of that class may not exist.

Here the design breaks. If your "target" class has to know what the
derived class is, then you cannot claim that it interfaces through
the base class.
Two
possibilities I have come up with are to 1) pass the static function
of the dervied class to the target class as a callback function or 2)
add the interface to the abstract base class, remove the static
designation of the function in the derived class, and use a half-
initialized object (ughh!) to access the function through a pointer to
the base class.

Sound like in the latter case you're concerned that 'Target::aFunc'
or 'Target::bFunc' can be called for partially constructed object.
That's a major limitation.

The function pointer in the case of partially constructed object
might be just as bad an idea as a virtual function. What is the
role of the static 'DerivedNFunc'?

Another question: can more than one of DerivedN classes inherit from
the same Base specialisation?

I guess I am still struggling with the fact that you need to have
and call the 'DerivedNFunc' in the 'Target' that isn't supposed to
know anything about the derived class (since all of its interface
is designed to use Base, at least so far)...
Is there a better, more elegant way to do this?

Thanks,
Carl

Code example below.


template <typename T>
class Base
{
public:
// illegal to declare a virtual static function here
virtual void func1(T& a) = 0;
virtual void func2(T& b) = 0;
// ...
};

class Derived1 : public Base<int>
{
public:
static void Derived1Func(int& x); // type T is int in this case
void func1(int& a);
void func2(int& b);
// ...
};

class XyzType
{
XyzType() {}
~XyzType() {}
};

class Derived2 : public Base<XyzType>
{
public:
static void Derived2Func(XyzType& x); // type T is XyzType here
void func1(int& a);
void func2(int& b);
// ...
};

template <typename T>
class Target
{
void aFunc(Base<T> *ptr);
void bFunc(Base<T> *ptr);
// ...
};

template <typename T>
void Target<T>::aFunc(Base<T> *ptr)
{
T aT;

ptr->func1(T& aT); // great, works fine
};

template <typename T>
void Target<T>::bFunc(Base<T> *ptr)
{

// now here I need to get a handle on Derived1Func or Derived2Func
// ... or DerivedNFunc depending on the T parameter, or some other
parameter
// if necessary. But I cannot call any of them directly because this
class
// primarily uses an interface to reference the specific derived
class
// (and does not know or care which derived class it is)


};

V
 
C

cmonthenet

That's what's happening, but it doesn't seem to be the design intent.
It interfaces with the base class object via a pointer to it. Whoever
is hiding behind that pointer should be immaterial to your "target"
class, if everything is designed correctly.

No, it is clearly the intent of the design to interface with any
object derived from the abstract base class through the base class'
interface.

Here the design breaks. If your "target" class has to know what the
derived class is, then you cannot claim that it interfaces through
the base class.

Well, the design does not break per se. It is not complete. It is the
reason for my post. I need to find a way to call a static function
associated with the derived class I am interfacing to through the
abstract base class interface. It would be ideal (?) if that call
could take place through an additional function in the interface, but
it does not seem possible for a static function.

Sound like in the latter case you're concerned that 'Target::aFunc'
or 'Target::bFunc' can be called for partially constructed object.
That's a major limitation.

I do not like option #2 and am looking for a better solution.
The function pointer in the case of partially constructed object
might be just as bad an idea as a virtual function. What is the
role of the static 'DerivedNFunc'?

No, it is not so bad. The static function is a hash function that
takes a key (the T parameter)
as a parameter and returns a hash value. The hash value is then used
to retrieve an item from a hash table and, if found, is returned to
the caller. The hash function only operates on the key and therefore
does not require the derived class to be instantiated and, as I
indicated, in some cases it will not be instatiated. The derived
classes represent different items that can be stored in different
instantiations of the "target" class.

Another question: can more than one of DerivedN classes inherit from
the same Base specialisation?

The abstract base class represents the minimal interface needed by the
"target" class to interface to a particular item. Each of the n
derived (item) classes inherits from the same abstract base class.

I guess I am still struggling with the fact that you need to have
and call the 'DerivedNFunc' in the 'Target' that isn't supposed to
know anything about the derived class (since all of its interface
is designed to use Base, at least so far)...

Well, I'm struggling too :). I am trying to come up with a good
solution to this issue, but so far passing in a callback function that
can be invoked at any point (without requiring a derived object to be
instantiated) seems to be the "best" solution that I can think of.
However, it seems to be me that a more clever solution might be found.
If you have any ideas, I would be interested in hearing them.
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top