create clojure proxy of abstract java class with overloaded same-arity method - clojure

is it possible to proxy a class like this and override both methods?
public abstract class C {
...
public abstract void m(String a);
public void m(Integer a) {}
}
this doesn't work:
(proxy [C] []
(m [^String a])
(m [^Integer a]))
;; java.lang.IllegalArgumentException: Method 'm' redefined
my current workaround is to write a proxy-friendly java class that renames the overload:
public abstract class C2 extends C {
#Override
public void m(Integer a) { this.m2(a); }
public abstract void m2(Integer a);
}
but would be nice to have a solution that doesn't require javac in the build

Include one method m in your proxy. Do not type-hint the parameter. Let the function check the actual parameter type at run-time and behave accordingly.
(If the methods in question differed in arity, you would need to declare the proxy method argument list as [ & x], i.e., receiving all parameters, however many they might be, as a vector. This technique helps when you want to proxy java.io.Writer for example.)

Related

Downcasting to furthest subclass when calling templated function

I use LuaBridge to import a large framework of classes into a Lua-accessible framework. LuaBridge uses complex template functions that maintain a list of linkages back to methods and properties of each class. The Lua language itself is loosely typed, and it does not check to see if a method or property exists until you call it. My framework implements a ClassName method at every level that allows the Lua programs to know which class it is dealing with.
That's just background for my program. This is a C++ question. I would like to call a function that, in its broadest abstraction, looks something like this:
template <typename T>
do_something_in_lua(T * object); // LuaBridge will create a pointer to a T instance in Lua
and call it like this:
class foobase
{
public:
void notify_lua()
{ do_something_in_lua(this); }
};
class foo : public foobase
{
public:
int some_method();
};
foo x;
x.notify_lua();
My question is, is there a simple way for do_something_in_lua to use the maximally downcasted version of T? Either when I call it or in the templated function? Using dynamic_cast is difficult because I would have to maintain an explicit list of every possible subclass to find the right one. Even if it is adding a templated virtual function in foobase that returns the desired type of this, I would be interested in suggestions for an elegant solution.
I guess a broader version of my question would be, does modern C++ provide any tools for downcasting in template programming (e.g., in type_traits or the like) that I should be investigating?
Thanks to several helpful comments, the solution turns out to be a hybrid of CRTP and Double Dispatch. Here is a version of it based on my example above. I like the fact that it
requires no pure virtual functions
does not require templatizing the base class (for reasons specific to my code base)
If I ever need to add a new subclass, I just need to add it to the list in the std::variant, and better yet, the compiler will complain until I do so.
template <typename T>
void do_something_in_lua(T * object);
// every subclass of foobase must be listed here.
class foosub1;
class foosub2;
using foobase_typed_ptr = std::variant<foosub1*, foosub2*>;
class foobase
{
foobase_typed_ptr _typedptr;
public:
foobase(const foobase_typed_ptr &ptr) : _typedptr(ptr) {}
void notify_lua()
{
std::visit([](auto const &ptr)
{ do_something_in_lua(ptr); },
_typedptr);
}
};
class foosub1 : public foobase
{
public:
foosub1() : foobase(this) {}
int some_method1();
};
class foosub2 : public foobase
{
public:
foosub2() : foobase(this) {}
int some_method2();
};
// and to call it in code:
foosub2 x;
x.notify_lua(); // now Lua gets called with a foosub2* instead of a foobase*.

Multiple inheritance: accessing common interface

Given the following:
class A {
//
}
class B {
//
}
class Ad1 : public A {
//
}
class Ad2 : public A {
//
}
class Ad1B : public Ad1, public B {
//
}
class Ad2B : public Ad2, public B {
//
}
Types Ad1B and Ad2B share a common inherited interface (the combined interface of A and B).
Is it possible to create a pointer to which objects of either type Ad1B or Ad2B can be assigned, and through which this shared interface can be accessed? Is there any way to achieve the same effect?
The common interface of Ad1B and Ad2B is A and B - so you could store pointer to object of class Ad1B or Ad2B either in A*p or in B*p and access A or B functionality respectively
You want a pointer to a base class that doesn't exist. You want some pointer to a type that have a combined interface of A and B. You must create a new type that have that interface.
You may pick three approaches : the template approach or the, the interface approach, or the adapter approach.
template
The template approach is quite easy. Your function that need that combined interface simply receive a reference to a T and user your object. If T have that combined interface, it will compile. It will even work with public data members.
interface
The interface approach will need to make changes to your classes. You may create that interface like this :
struct AB {
// Add virtual member function
// That is the combined version of A and B
};
Now Ad1B and Ad2B must inherit from the AB interface.
adapter
The adapter is a mix of the template and the interface. You must have an interface AB just as above, but instead of making Ad1B and Ad2B implement it, you create a templated adapter :
template<typename T>
struct Adapter : AB {
T& object;
// Override foo from AB
void foo() override {
object.foo();
}
};
You can then use the AB interface in your code. Where you'd use the combined interface.

Slightly derive a class without loosing access to its constructors

Suppose I have a large class with a lot of functionality and a relatively large interface. Particularly, there are many constructors for convenient instantiation. From this class, several classes could be derived with some slightly extended interface and/or customized virtual functions.
The problem: I will have to copy all the constructors into the derived classes which would mean a lot of code duplication. Even worse: The constructors slightly depend on the derived class, which I would solve by a virtual call, but this does not work in a constructor.
What's a good approach to tackle this problem?
EDIT: I know that I can delegate constructors Derived(arguments) : Base(arguments) {} but I'd still need to copy parts of the constructor which I try to avoid.
Use using declarations to make the constructors of the base class aviable on the derived one:
class Base
{
public:
Base( int , int , int );
};
class Derived : public Base
{
public:
using Base::Base; //Automatically adds all the base constructors
};
EDIT: Here is a running example.
I do not know exactly if it works for your problem, but you might think about making some kind of 'initialization' object where you handle the properties of the object you want to create. This will have a lot of constructors.
Then you pass this object to the 'real' class where the properties are used to create the actual object.
If C++ 11 extensions can be used, then the other answer that recommends using is a perfect answer.
If not, then the only way is:
class x: public y
{
// modified constructors:
x (int a) : y (1, 2, a + 3) { your code if any; }
x (int a, int b) : y (b, a) { your code if any; }
// delegated constructors: alas, repeated for all constructors of y
x (int c, float d) : y (c, d) { /* no code*/ }
x (float e, int f) : y (e, f) { /* no code*/ }
}
The latter part is not really code duplication because you only duplicate interface but no code.
Do the initializations applicable in respective classes. For example, say A is superclass and B is a subclass, so you may use,
B::B(...arguments...): A(...arguments that you would like to pass to superclass constructor)
{
}

Multiple Inheritance with abstract and defined inherited functions of the same name

First off I apologize if there is another post out there that answers this, all the similar posts I found dealt with diamond inheritance schemes or defined functions, which this does not.
In short, I'm wondering if it is possible to have one class inherit from two other classes where both child classes has a function with the same name and arguments but it is defined in one child class, and pure-virtual in another. Furthermore if I can do this, would invoking the function on the pure-virtual/abstract class end up calling the defined function on the other child class with minimal changes to the derived class?
Example:
class A
{
public:
virtual void Set(int X) = 0;
};
class B
{
public:
virtual void Set(int X);
};
class AB : public A, public B
{
//other methods not relevant to example go here
};
int main(int argc, char **argv)
{
int Y = 5;
A* ObjectA = new AB();
ObjectA->Set(Y);
return 0;
}
So far my attempts to compile this basic example have been met with errors that say:
'AB' : cannot instantiate abstract class
due to following members:
'void A::Set(int)' : is abstract
When doing my own research I couldn't find a clear answer, but based on other questions that dealt with related topics I found that using a "using B::Set" in class AB may help with this. But when I try adding it to the AB class definition, the error persists.
Is there any way I can make this work?
If you had 2 normal functions Set in A and B, then using B::Set would tell the compiler that if you have object of class AB and call method Set of that object, B::Set will be invoked, if AB::Set not defined explicitly.
Your situation is different. You have pure virtual function A::Set that leads A to be abstract class. As AB does not override A::Set, AB becomes abstract too, that is why you cannot instantiate it.
What you can do here
You can implement AB::set to call B::Set:
class AB : public A, public B
{
public:
void Set(int x) { return B::Set(x); }
};
Also I do not recommend same method names for base classes, as I do not recommend multiple inheritance, try use aggregation instead.
Have you tried implementing the method:
class AB : public A, public B
{
void Set(int X) {}
};
The reason it's not working is that A::Set() is pure virtual. I.e. it has no implementation. But you try to call it. You have to override it in the derived class in order to be able to instantiate the derived class.
The using doesn't work in your case because you have an A*, so there's no ambiguity for the compiler.
In case you had:
AB* ObjectA = new AB();
ObjectA->Set(Y);
you'd have to use using inside the declaration of AB to resolve the ambiguity.
Class AB derives from A, A has a pure virtual method making the class abstract, AB must implement any pure virtual methods declared in a base class in order to be instantiated.
I would try to avoid multiple inheritance it can cause many headaches and there are generally better ways to solve a problem, for instance in this example I don't understand the point in deriving from both A and B, if B shares and in fact implements the same interface as A then surely B should be derived from A.

C++ casting a base pointer to an interface pointer

Here is some pseudo code of my setup:
class IMyClass { ... }; // pure virtual class
class CMyBaseClass { .... };
class CMyClass : public CMyBaseClass, public IMyClass { ... }
Then I have collection of CMyBaseClass*. I have custom RTTI that allows me to find out if a class implements given interface. So I can find which of the objects have IMyClass implementation. My problem is that I can't cast it to that interface. I don't want to use standard RTTI and dynamic cast.
I'm thinking in my custom RTTI to store some pointer diffs for casting between pair of classes, but I haven't figure out implementation that makes me happy.
Any other solutions?
Well, if you insist in not using the language RTTI, you can use just like the old COM: make all your classes or interfaces derive from the following interface:
class IMyCast // similar to IUnknown
{
public:
virtual void *CastTo(interfaceId_t id) = 0; //Similar to IUnknown::QueryInterface
};
Now in your CMyClass:
class CMyClass : public CMyBaseClass, public IMyClass
{
//...
void *CastTo(interfaceId_t id)
{
switch (id)
{
case IMyClass_id: //or whatever
return static_cast<IMyClass*>(this);
//...other cases
default:
throw std::bad_cast(); //or return NULL
}
}
};
Then in the user code:
CMyBaseClass *obj;
IMyClass *my = static_cast<IMyClass*>(obj->CastTo(IMyClass_id));
Probably you'll need to augment your custom RTTI; at least this is what I did in pretty much the same situation. Instead of using pointer diffs, my solution instantiates a "caster" function template for the necessary (Class, Interface) pairs. It's something like this:
All interfaces have a unique int id. For this a MyInterface needs to be derived from InterfaceBase. The id is assigned automatically on the first MyInterface::GetId() call.
The implementor of MyClass (that implements MyInterface) needs to add an IMPLEMENTS(MyClass, MyInterface) macro in a .cpp file.
The macro instantiates a void* GetInterface<C, I>(void*) function, and then registers a pointer to this function in an interfaceId -> GetInterface-function map (that belongs to class C). This function casts its argument into C*, then the C* into I*, and finally back to void*. (The hacking with void*'s is necessary so that all these functions have the same signature, thus they can be stored in a map.)
To get an interface, the user needs to call a myObject->GetInterface() function, implemented in CMyBaseClass. It finds the map that belongs to the dynamic class of the this object, looks up the appropriate caster function based on I::GetId(), and calls it passing this.