Is there anyway I can use a static function contained in a class froman object.

J

Jim

Hi,
I'm passing an object to another type of object, and would like it to
have access to a public static function contained in the original
object's class, is that possible? I have two types of object each
derived from a base class, each with their own static function of the
same name.

This could possibly be achieved more simply overloading static
variables, I think, but I don't know if that's possible.

Thanks,
James
 
G

Gert-Jan de Vos

Hi,
I'm passing an object to another type of object, and would like it to
have access to a public static function contained in the original
object's class, is that possible? I have two types of object each
derived from a base class, each with their own static function of the
same name.

You mean like:

class A
{
public:
static void f() {}
};

class B
{
public:
static void f(const A& a)
{
a.f();
}
};

Sure no problem, did you try? Please post a small concrete example of
your problem in compilable code.
 
P

P. Lepin

Jim said:
I'm passing an object to another type of object, and would like it to
have access to a public static function contained in the original
object's class, is that possible? I have two types of object each
derived from a base class, each with their own static function of the
same name.

I got somewhat interested by this problem (although the right
way to fix it is probably to use non-static virtual member
functions). Not a C++ expert here, so take everything below with
a grain of salt.

There seems to be a way to achieve this without modifying the
"library" code, but it's ugly-ish and will require extensive
changes to the client code:

#include <iostream>
#include <ostream>
#include <string>
#include <vector>
#include <cassert>

class Base {
public:
virtual ~Base() {}
virtual std::string getTypeInfo() = 0;
};

class Derived1 : public Base {
public:
std::string getTypeInfo() { return "Derived1"; }
static void doStuff() {
std::cout << "Stuff appropriate for Derived1" << std::endl;
}
};

class Derived2 : public Base {
public:
std::string getTypeInfo() { return "Derived2"; }
static void doStuff() {
std::cout << "Stuff appropriate for Derived2" << std::endl;
}
};

class BaseWrapper {
public:
virtual void doStuff() = 0;
};

template<class T> class Wrapper : public T, public BaseWrapper {
public:
void doStuff() { T::doStuff(); }
};

int main() {
std::vector<Base *> objects;
objects.push_back(new Wrapper<Derived1>);
objects.push_back(new Wrapper<Derived2>);
objects.push_back(new Derived2);
for (std::vector<Base *>::iterator i = objects.begin();
i != objects.end(); ++i) {
std::cout << (*i)->getTypeInfo() << std::endl;
BaseWrapper *bw = dynamic_cast<BaseWrapper *>(*i);
assert(bw != NULL);
bw->doStuff();
delete *i;
}
return 0;
}

As you can see, you'll have to use Wrapper<Derived> objects
instead of Derived objects, and you'd probably want to check
explicitly whether your cast worked to avoid all sorts of mayhem
imminent upon dereferencing a NULL pointer.

It becomes a little more pleasing to the eye if your Derived
classes use virtual inheritance from Base (or if that's a change
you can, and are willing to make):

#include <iostream>
#include <ostream>
#include <string>
#include <vector>

class Base {
public:
virtual ~Base() {}
virtual std::string getTypeInfo() = 0;
};

class Derived1 : public virtual Base {
public:
std::string getTypeInfo() { return "Derived1"; }
static void doStuff() {
std::cout << "Stuff appropriate for Derived1" << std::endl;
}
};

class Derived2 : public virtual Base {
public:
std::string getTypeInfo() { return "Derived2"; }
static void doStuff() {
std::cout << "Stuff appropriate for Derived2" << std::endl;
}
};

class BaseWrapper : public virtual Base {
public:
virtual void doStuff() = 0;
};

template<class T> class Wrapper : public T, public BaseWrapper {
public:
void doStuff() { T::doStuff(); }
};

int main() {
std::vector<BaseWrapper *> objects;
objects.push_back(new Wrapper<Derived1>);
objects.push_back(new Wrapper<Derived2>);
for (std::vector<BaseWrapper *>::iterator i = objects.begin();
i != objects.end(); ++i) {
std::cout << (*i)->getTypeInfo() << std::endl;
(*i)->doStuff();
delete *i;
}
return 0;
}

Of course, this way you'll also have to use BaseWrapper instead
of Base, but at least the cast is no longer there.

Please correct me if there is anything I'm missing or
misinterpreting.
 

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,780
Messages
2,569,610
Members
45,254
Latest member
Top Crypto TwitterChannel

Latest Threads

Top