0

I am using the JNI invocation API and I would like to be able to perform the following assignment in my main() function:

jobject Myjobject = MyClassInstance;

Where MyClassInstance is an object instance of MyClass.

MyClass.h:

// DEFINE OVERLOADED = OPERATOR //
    jobject operator= (const MyClass &);

MyClass.cpp:

jobject MyClass::operator =(const MyClass & MyInstance)
{
    return MyInstance.jobjectMember;
}

Where jobjectMember is a private jobject member of MyClass.

However, I keep getting the following error during compilation:

error: cannot convert ‘MyClass’ to ‘jobject {aka _jobject*}’ in assignment

Where am I going wrong?

kahamster
  • 51
  • 5

2 Answers2

2

In order jobject Myjobject = MyClassInstance; (which is initialization, not an assignment) to work you need to define a corresponding constructor for jobject class.

class jobject
{
    public: explicit
    jobject(MyClass const & that) {...}

or define conversion operator for MyClass

  class MyClass 
  {
      public: explicit
      operator jobject const &(void) const
      {
          return this->jobjectMember;
      }

  jobject Myjobject{static_cast<jobject const &>(MyClassInstance)};
user7860670
  • 35,849
  • 4
  • 58
  • 84
  • Might be worth to mention that `explicit` is not mandatory - without, one can drop the explicit cast. Good idea? Probably a matter of use case... Is there any good discussion about when to prefer one over the other? – Aconcagua Oct 29 '18 at 11:12
  • Hi thanks for your response. I am relatively new to C++ but the conversion operator is exactly what I was looking for. – kahamster Oct 29 '18 at 11:30
0

Just explaining why your code fails (how to solve: see VTT's answer):

jobject MyClass::operator=(const MyClass& MyInstance)
{
    return MyInstance.jobjectMember;
}

This would allow to assign an instance of MyClass be assigned another instance of – well, MyClass:

MyClass x, y;
x = y;

Now, however, while the code might be legal, it is at least very unusual, I'd rather say it is violating good practice or common conventions: Normally, the assignment operator returns the object being assigned – of correct type and by reference:

MyClass& MyClass::operator=(const MyClass& other)
{
    return *this;
}

This would allow to do things like these:

MyClass x, y, z;
x = y = z;

which is what people expect from assignment. Your variant, in contrast, would allow:

jobject o;
MyClass x, y;
o = x = y; // ???

Additionally, you expect, after assignment, the destination object being the same as the target object (more or less at least), so you'd normally copy the jobject as well:

MyClass& MyClass::operator=(MyClass const& other)
{
    jobjectMember = other.jobjectMember;
    return *this;
}

Finally: If already writing custom assignment operators, have a look at the rule of three and rule of five, they might help you avoid some trouble in the future.

Aconcagua
  • 24,880
  • 4
  • 34
  • 59