Sign in to follow this  
Kreative

Virtual / abstract class variables / functions that are shared across all instances of a class?

Recommended Posts

Kreative    211

Hello,

I consider myself to be very fluent with java syntax and I somewhat understand some parts of C# and C++. In java I have stumbled across a problem in my game programming that I cannot resolve, I have searched for a workaround or solution for the problem on different forums and websites, I also asked this in a few forums myself, however nothing nor' no one gave me any solution, adequate in my view, nor' convinced me that it's better to disallow a basic unimplemented solution that I myself and many other people have had as their first thought to this problem.

From my understanding, neither java nor' C++ allow the virtual / abstract modifier with the static modifier and I believe I understand why, considering what the static modifier does. However in java, you cannot force inherited classes to provide an implementation for an identifier (field or method) within a class that is shared across all instances of the class and can be accessed without the need to instantiate the class. I think this would be an extremely useful feature, but before replying, please do consider that, in computer science theory, I consider myself to be somewhat naive.

Kind Regards,
Kreative

Share this post


Link to post
Share on other sites
SimonForsman    7642

Hello,

I consider myself to be very fluent with java syntax and I somewhat understand some parts of C# and C++. In java I have stumbled across a problem in my game programming that I cannot resolve, I have searched for a workaround or solution for the problem on different forums and websites, I also asked this in a few forums myself, however nothing nor' no one gave me any solution, adequate in my view, nor' convinced me that it's better to disallow a basic unimplemented solution that I myself and many other people have had as their first thought to this problem.

From my understanding, neither java nor' C++ allow the virtual / abstract modifier with the static modifier and I believe I understand why, considering what the static modifier does. However in java, you cannot force inherited classes to provide an implementation for an identifier (field or method) within a class that is shared across all instances of the class and can be accessed without the need to instantiate the class. I think this would be an extremely useful feature, but before replying, please do consider that, in computer science theory, I consider myself to be somewhat naive.

Kind Regards,
Kreative


Why would you want to re-implement a static method in a child class ? since the static method won't use the instance anyway you can always access it using Baseclass.staticmethod() (from anywhere if it is public and from the child classes if it is protected)

Share this post


Link to post
Share on other sites
WozNZ    2010

I doubt there is a single language that will support abstract overriding of a static function within a class, it makes no sense, static is outside the inheritance tree.

 

It depends what you are trying to do as to how you handle it, to me it sounds like you really need a member function to give you the overloading you want or have the static function take the instance being operated on and use that to call a virtually routed member function on the instance to provide your virtual routing.

 

What is the problem you are actually trying to solve or is this more an academic around static? 

Share this post


Link to post
Share on other sites
Nypyren    12074
Usually when you encounter this problem, your only option is to use functional style (passing functions to your static functions in this case).

But it might also mean you need to redesign your code.

Share this post


Link to post
Share on other sites
WozNZ    2010

As stated by Nypyren, the functional route might be what you are actually after. This is in C# as my Java is a bit rusty 

 

Here we have an abstract base class that also has a static function. The difference being that the static function only does part of the work and expects the caller to pass in another function with the rest of the work to be carried out. The call to someOperation(instance) can be thought of calling an overloaded function if you like except the caller has supplied it instead of coming from an inheritance tree via virtual routing

The supplied example is contrived and does not really touch on the subject of what functional is really about but might be enough to make you think outside the box a little :)

 

public abstract class MyBaseClass

{

    // Some non static stuff here

 

    public static string DoSomeStaticThing(MyBaseClass instance, Func<MyBaseClass, string> someOperation)

    {

        string headerMessage = // some work in the static function to get this header message

        string footerMessage = // some work in the static function to get this footer message

 

        return headerMessage + someOperation(instance) + footerMessage;

    }

}

Share this post


Link to post
Share on other sites
Kreative    211

I don't like using the word static because generally what I'm trying to achieve IS NOT outside the inheritance tree, something THAT is inherited YET shared across instances and therefore accessible without the need of instantiating. I'll give an example that nobody explained how to fully solve, (Java):

public class Vehicle {
	// public final static int wheel; inherited and shared
	public final String name;
	
	public Vehicle(String name) {
		this.name = name;
	}
}

public class Car extends Vehicle {
	public final static int wheels = 4;
	
	public Car(String name) {
		super(name);
	}
}

public class Motorcycle extends Vehicle {
	public final static int wheels = 2;
	
	public Motorcycle(String name) {
		super(name);
	}
}

I could share this across all instances by simply putting it into a method that returns the value for wheels and make it static, but then it won't be initialized differently in sub-classes or accessible without the need for instantiation. However, I could put it into a non-static, abstract method returning a value for the number of wheels, however then it won't be accessible without the need for instantiation, then I could create a singleton static method, though I have no way of enforcing the creation of a singleton method in every sub-class including those that aren't made by me in cases such as game modding.

Kind Regards,
Kreative

Share this post


Link to post
Share on other sites
Nypyren    12074

(Vehicle example)



If you have an instance of the non-abstract base class "Vehicle", how many wheels does it have?

If you have a Boat, which is intuitively a vehicle, how many wheels does it have?

Use composition, not inheritance. Edited by Nypyren

Share this post


Link to post
Share on other sites
SmkViper    5396
Nypyren is correct. "Wheels" are not inherent to "vehicle", you should be considering composition.

However, to take your example and provide what you want (I think), you can easily do it this way:
 
class Vehicle
{
public:
  virtual int GetWheels() const = 0;
};

class Motorcycle: public Vehicle
{
public:
  static const int Wheels = 2;

  virtual int GetWheels() const override {return Wheels;}
};

class Car: public Vehicle
{
public:
  static const int Wheels = 4; // Hopefully we're not a Reliant Robin

  virtual int GetWheels() const override {return Wheels;}
};
And you use it like so:
// How many wheels does this unknown vehicle have?
std::cout << "My vehicle has " << MyVehicle.GetWheels() << " wheels\n";
// How many wheels does a car have?
std::cout << "A car has " << Car::Wheels << " wheels\n";
Asking "How many wheels does a vehicle have?" is meaningless without either knowing which vehicle (virtual call with instance) or what kind of vehicle (concrete type with static var), so a static accessor/variable in Vehicle does not make sense. (And even then, not all cars have 4 wheels either) Edited by SmkViper

Share this post


Link to post
Share on other sites
phil_t    8084

You could also use composition like this:


// Chassis traits common to all vehicles
struct ChassisTraits
{
    int WheelCount;
    std::string FrameMaterial;  // I dunno...
};

// The traits for different kinds of vehicles:
const ChassisTraits CarChassisTraits = { 4, "Carbon fiber" };
const ChassisTraits MotorcycleChassisTraits = { 2, "Metal" };
const ChassisTraits ReliantRobinChassisTraits = { 3, "Unkonwn" };

// A single class for all vehicles
class Vehicle
{
public:
    Vehicle(const ChassisTraits &traits) : Chassis(traits)
    {

    }

    const ChassisTraits &Chassis;
};

// Some factory functions, if you want...
Vehicle *CreateCar() { return new Vehicle(CarChassisTraits); }
Vehicle *CreateMotorcycle() { return new Vehicle(MotorcycleChassisTraits); }

Then you can ask the question of both an individual instance, or a certain type of vehicle:

    Vehicle *unknownVehicle; // ....
    // How many wheels does this unknown vehicle have?
    std::cout << "My vehicle has " << unknownVehicle->Chassis.WheelCount << " wheels\n";
    // How many wheels does a car have?
    std::cout << "A car has " << CarChassisTraits.WheelCount << " wheels\n";

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this