invoking static methods of derived class

K

ketan

Hi All,

I have a situation where in I need to call static methods of the
derived class. I checked previous posts, but could not get any
satisfactory reply.

My situation can be simulated with following code.

//
// Does not compile. Not correct C++ syntax - shows what needs to be
done.
//
#include <iostream>

class Vehicle
{
public:
void show() { std::cout << " Vehicle " << std::endl; }
void stop(void)
{
std::cout << " Vehicle stopped " << std::endl;
Car::stop();
Bus::stop();
}
};

class Car : public Vehicle
{
public:
Car();
~Car();
void show() { std::cout << " Car " << std::endl; }
// knows how to stop Car
static void stop(void) { std::cout << " Car stopped " << std::endl;
}
};


class Bus : public Vehicle
{
public:
Bus();
~Bus();
void show() { std::cout << " Bus " << std::endl; }
static void stop(void) { std::cout << " Bus stopped " << std::endl;
}
};


int main()
{
Vehicle v;
Vehicle::stop();
}

Situation can be something like this, assume that some car or bus are
moving and we don't know which are moving (each class internally tracks
all active instant etc.) So we want to call a static method which will
ensure that any type - Car or Bus if active will stop.

So I need to call some static method in base class, which internally
can assure that all derived types will stop if they are moving.

I am not able to figure out how to solve this problem or any alternate
way to solve the base problem.

Thanks
Ketan
 
D

ddtbhai

Hi Ketan,

if i understand correctly, you are trying to invoke a standard base
class function that will eventually invoke a dervied class
implementation of the function. This is where virtual functions have to
be used.

so, your code will sth like this :

class Vehicle
{
Vehicle();
virtual ~Vehicle();
public:
virtual void show() { std::cout << " Vehicle " << std::endl; }
virtual void stop() { std::cout << " Vehicle stopped" <<
std::endl; }
};

class Car : public Vehicle
{
public:
Car();
~Car();
void show() { std::cout << " Car " << std::endl; }
void stop(void) { std::cout << " Car stopped " << std::endl; }
};

int main()
{
Vehicle* vPtr = new Car( ); // usually u will manage such
instances with base class
// pointers so that you
don't have to know in advance
// what type they are.
vPtr->stop( ); // will call Car's method

}

Hope i've expressed myself in a simple fashion !
I don't think your situation requires the invocation of static
functions of derived classes in the base class... (which is a bad idea
generally)
 
N

Nate Barney

ketan said:
I have a situation where in I need to call static methods of the
derived class. I checked previous posts, but could not get any
satisfactory reply.

[ snip code ]

I think you're confused as to the purpose of static functions. What you
want in this case is nonstatic virtual functions. Something like:

#include <iostream>

class Vehicle
{
public:

virtual ~Vehicle() {} // note the virtual destructor here
virtual void show() { std::cout << " Vehicle " << std::endl; }
virtual void stop()
{ std::cout << " Vehicle stopped " << std::endl; }
};

class Car : public Vehicle
{
public:

virtual void show() { std::cout << " Car " << std::endl; }
virtual void stop()
{ std::cout << " Car stopped " << std::endl; }
};

class Bus : public Vehicle
{
public:

virtual void show() { std::cout << " Bus " << std::endl; }
virtual void stop()
{ std::cout << " Bus stopped " << std::endl; }
};

int main()
{
Vehicle v;
v.stop(); // call the function on the object, not the class
}

Read more about inheritance and virtual functions.

Hope this helps,
Nate
 
K

ketan

Hi Nate,

I am aware of virtual function usage.

But may be I was not clear in my requirement. Let me summarize again,

1) I need static method as It can be invoked anytime _without_
reference to the active object type. Since I cant access object
pointer.

2) I need to call this method on all derived classes. Assume that on
road, cars and busses both are running (assume that only one instance
of each type is running at given time). So when I call stop:: I need
both of them to stop.

So I am not looking for polymorphic or dynamic binding of methods.

I hope, I could explain my situation better.
Thx
Ketan
 
N

Nate Barney

ketan said:
Hi Nate,

I am aware of virtual function usage.

But may be I was not clear in my requirement. Let me summarize again,

1) I need static method as It can be invoked anytime _without_
reference to the active object type. Since I cant access object
pointer.

2) I need to call this method on all derived classes. Assume that on
road, cars and busses both are running (assume that only one instance
of each type is running at given time). So when I call stop:: I need
both of them to stop.

So I am not looking for polymorphic or dynamic binding of methods.

Well, I think you seriously need to rethink your design then. You
shouldn't be using static functions in this case, IMHO. What about a
Road class that has a container of Vehicles? Then you could have a
stop() method on the Road class that would iterate over the Vehicles and
call the virtual stop() function for each of them.

However, against my better judgment, I offer this as something that
might be interesting:

#include <iostream>
#include <vector>

class Vehicle
{
public:

typedef void(StopFunc)(void);
typedef std::vector<StopFunc*> StopVec;

void show() { std::cout << " Vehicle " << std::endl; }
static void addStopFunc(StopFunc *sf) { stopVec.push_back(sf); }
static void stop(void)
{
std::cout << " Vehicle stopped " << std::endl;

for (StopVec::iterator i = stopVec.begin();
i != stopVec.end(); ++i)
(*i)();
}

private:

static StopVec stopVec;
};

Vehicle::StopVec Vehicle::stopVec;

class Car : public Vehicle
{
public:
Car();
~Car();
void show() { std::cout << " Car " << std::endl; }
// knows how to stop Car
static void stop(void)
{ std::cout << " Car stopped " << std::endl; }
};

class Bus : public Vehicle
{
public:
Bus();
~Bus();
void show() { std::cout << " Bus " << std::endl; }
static void stop(void)
{ std::cout << " Bus stopped " << std::endl; }
};

int main()
{
Vehicle::addStopFunc(Car::stop);
Vehicle::addStopFunc(Bus::stop);
Vehicle::stop();
}
 
K

ketan

Hi Nate,

Thanks for the detailed explanation.

Yes, I did rethink about my design and will do required changes. Also
discussed requirement and i think polymorphic invocation would suffice
(yes any one instance only).

It was nice to know what CAN'T be done or assert again that when you
run into such issues -- rethink design :)

thx
Ketan
 
N

Nate Barney

Nate said:
What about a Road class that has a container of Vehicles? Then you
> could have a stop() method on the Road class that would iterate over
> the Vehicles and call the virtual stop() function for each of them.

I neglected to mention that if you do something like this, you'll need
to store a container of Vehicle*, not Vehicle, because otherwise you'll
have a slicing problem and polymorphism won't work. Additionally,
you'll need to make sure you delete the pointers before you clear the
container, either by explicitly iterating over them and deleting them
manually, or by storing some sort of smart pointer in the container.

Nate
 

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,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top