You have created your own, unnecessary problem here.
- Everything must be runnable
- The default implementation of run requires proc
- Anybody implementing their own run can ignore proc (but all that useless code still adorns the class and any descendants).
- Your concrete, exception-throwing implementation of proc enables people to set up themselves up for runtime errors. Why do that?
OK, so you wanted to be helpful by providing a default implementation but you have bolted on implementation details which you know will not always be desired. You say you want to avoid code duplication but you have encumbered your hierarchy with code which will be obsolete as soon as somebody extends it.
I would strongly urge you to go the interface/abstract-base-class route here:
- Abstract base class runnable
- Abstract base class proccer
- Create proc-calling concrete implementation of runnable.
- Wherever possible (even in proc-caller class methods) refer to runnables and not proc-callers).
So your default run implentation can be used where desired but can be dropped without penalty. Also, this way people are forced to implement proc if they mix in proc-caller but you don't have to write that "Not implemented" version of proc - they can't compile their code if they do not implement proc. Why create that runtime trap when you can require them to fix things at compile time?
If you think there are other useful behaviours which should be available, you can avoid code duplication by providing "interfaces" in the same way I have shown for proc. Anybody who wants that can mix it in.
Inheritance not helping to eliminate repetition and typecasts is often a sign that generics would help. You can do something like:
public T getTranspose<T>()
// or non-member function
T getTranspose<T>(T input)
I haven't fully worked it out, but it seems it might get awkward on the calling side. I know C# does some inference with generic methods, but I don't know C#, so I'm not familiar with the details. That might be the way you have to go, though, if you want full compile-time type checking with the least amount of repetition in the implementation.
Another option would be to create private helper functions, then pass in the result type you want, for the helper to populate, like:
public SquareMatrix getTranspose() {
SquareMatrix result = new SquareMatrix();
transposeHelper(result);
return result;
}
This gives you more boilerplate on the implementation side, but at least it isn't full repetition.
A third option is just to check if the result is square in the Matrix
implementation, and return a SquareMatrix
if it is, like:
public Matrix getTranspose() {
Matrix result;
if (resultIsSquare())
result = new SquareMatrix();
else
result = new Matrix();
// calculate result
return result;
}
This has the advantage of not needing any implementation at all for getTranspose()
in SquareMatrix
, but at the expense of requiring type checking of the return value at the call site. It also works for cases like multiplying two non-square matrices that happen to give a square result. You give up most compile-time type checking, though.
If your application happens to mostly require run-time instead of compile-time type checking anyway, you might as well just give up the different types and throw an exception if you call a method that a non-square matrix doesn't support. I believe this is the approach most existing libraries take, especially since there are other conditions than being non-square that can cause methods like inverse()
to fail.
Speaking of libraries, there are a lot of good ones out there for matrix math, that are already heavily tested and optimized. Don't reinvent the wheel if you don't have to.
Best Answer
You can specify base class with virtual function Update and derived classes overriding this function. Here is simple example:
Then create a vector of pointers to base class and fill with objects of specific type:
And your UpdateAll function can look like this:
Because you are using pointers, don't forget to release all allocated memory at the end of game.