Menu

#1205 Overriding Parent Member Functions

open
nobody
5
2023-08-07
2011-11-09
No

To understand the bug I am reporting, consider the example SWIG interface file below which defines 5 classes, 4 of which (i.e., 'ClassA', 'ClassB', 'ClassC', 'ClassD') form a linear hierarchy , and 1 of which (i.e., 'ClassX') forms the parameter type of an overloaded parent class function, which is overridden by its child class.

===
%module(package="MyApp", docstring="Simple Example") test

namespace MyApp { namespace nsOne { namespace nssOneOne {
class ClassX
{
public:
ClassX();
};
}}}

namespace MyApp { namespace nsTwo { namespace nsTwoTwo {
class ClassA
{
public:
typedef nsOne::nsOneOne::ClassX ClassX;

      ClassA\(\);

      virtual double MyFunc\(double d\);
      virtual double MyFunc\(const ClassX& p\) const;

};
}}}

namespace MyApp { namespace nsTwo { namespace nsTwoTwo {
class ClassB : public ClassA
{
public:
typedef ClassA::ClassX ClassX;

      ClassB\(\);

};
}}}

namespace MyApp { namespace nsTwo { namespace nsTwoTwo {
class ClassC : public ClassB
{
public:
typedef ClassB::ClassX ClassX;

      ClassC\(\);

};
}}}

namespace MyApp { namespace nsTwo { namespace nsTwoTwo {
class ClassD : public ClassC
{
public:
ClassD();

      using ClassC::MyFunc;
      double MyFunc\(const ClassX& p\) const;

};
}}}
===

The resulting java definition created for 'ClassD' will look as follows:

===
public class ClassD extends ClassC {
private long swigCPtr;

public ClassD(long cPtr, boolean cMemoryOwn) {
super(testJNI.ClassD_SWIGUpcast(cPtr), cMemoryOwn);
swigCPtr = cPtr;
}

public static long getCPtr(ClassD obj) {
return (obj == null) ? 0 : obj.swigCPtr;
}

protected void finalize() {
delete();
}

public synchronized void delete() {
if (swigCPtr != 0) {
if (swigCMemOwn) {
swigCMemOwn = false;
testJNI.delete_ClassD(swigCPtr);
}
swigCPtr = 0;
}
super.delete();
}

public ClassD() {
this(testJNI.new_ClassD(), true);
}

public double MyFunc(double d) {
return testJNI.ClassD_MyFunc__SWIG_0_0(swigCPtr, this, d);
}

public double MyFunc(ClassX p) {
return testJNI.ClassD_MyFunc__SWIG_0_1(swigCPtr, this, ClassX.getCPtr(p), p);
}

public double MyFunc(ClassX p) {
return testJNI.ClassD_MyFunc__SWIG_1(swigCPtr, this, ClassX.getCPtr(p), p);
}

}

In the above java class definition, notice that function "double MyFunc(ClassX p)" is defined twice. The first definition should not be created as it's a redefinition of the parent's function. Only the second definition should be created, which is the child's implementation of the overloaded function.

Discussion

  • William Fulton

    William Fulton - 2011-11-16

    Your C++ code is invalid...

    example_wrap.cxx:227: error: ‘MyApp::nsOne::nsOneOne’ has not been declared
    example_wrap.cxx:227: error: ISO C++ forbids declaration of ‘ClassX’ with no type
    ... lots more errors ...

    and consequently this lack of type information is reflected in the ClassD.java methods:

    public double MyFunc(SWIGTYPE_p_MyApp__nsOne__nsOneOne__ClassX p) {
    return exampleJNI.ClassD_MyFunc__SWIG_0_1(swigCPtr, this, SWIGTYPE_p_MyApp__nsOne__nsOneOne__ClassX.getCPtr(p));
    }

    public double MyFunc(SWIGTYPE_p_MyApp__nsOne__nsOneOne__ClassX p) {
    return exampleJNI.ClassD_MyFunc__SWIG_1(swigCPtr, this, SWIGTYPE_p_MyApp__nsOne__nsOneOne__ClassX.getCPtr(p));
    }

    Please submit the corrected C++ code to analyse further.

     
  • Prasant Rekapalli

    example test-case

     
  • Prasant Rekapalli

    I have uploaded a "compilable" version of the example listed above.

     
  • Olly Betts

    Olly Betts - 2022-03-19

    The updated example shows the same issue with SWIG git master.

    I think there's a duplicate report of this either here or in the current github tracker, but I'm failing to find it right now.

     
  • Olly Betts

    Olly Betts - 2023-08-07

    I retested as there have been some using fixes recently and the cause of this looks to be using ClassC::MyFunc; in ClassD, but this is still reproducible with current git master (2e1506c1896f90456e5b3092ba7c7200c1b1e2e1):

    $ ../preinst-swig -c++ -java example.i
    $ grep -A3 'public double MyFunc(ClassX p)' ClassD.java
      public double MyFunc(ClassX p) {
        return exampleJNI.ClassD_MyFunc__SWIG_1(swigCPtr, this, ClassX.getCPtr(p), p);
      }
    
      public double MyFunc(ClassX p) {
        return exampleJNI.ClassD_MyFunc__SWIG_2(swigCPtr, this, ClassX.getCPtr(p), p);
      }
    
     

Log in to post a comment.