Archived
This forum has been archived. Please start a new discussion on GitHub.
Generated constructors in derived classes do not pass params correctly to base class
JohnB
in Bug Reports
Hello,
When I pass a parameter through a base class constructor it does not seem to get set into the base class member variable. Here is a small repo case to demo
the problem. (Ice version is 3.3.0 for C++)
When I run this I get the following result.
./demo
Circle of radius:20 type:0
Assertion failed: type == CircleType, file demoTest.cpp, line 15
Compilation abort (core dumped) at Thu Mar 26 10:38:23
When I pass a parameter through a base class constructor it does not seem to get set into the base class member variable. Here is a small repo case to demo
the problem. (Ice version is 3.3.0 for C++)
--- demo.ice. ---
module demo
{
enum ShapeType {
Unknown,
RectangleType,
TriangleType,
CircleType,
SquareType
};
class Shape {
ShapeType type;
};
class Circle extends Shape {
int radius;
};
sequence<Shape> ShapeSeq;
};
-- demoTest.cpp --
#include "demo.h"
#include <iostream>
#include <assert.h>
using namespace std;
using namespace demo;
class CircleI : virtual public Circle
{
public:
CircleI(int rad)
: Circle(CircleType, rad)
{
cerr << "Circle of radius:" << radius
<< " type:" << type << endl;
assert(type == CircleType);
}
};
int main(int,char *[])
{
ShapeSeq shapes;
shapes.push_back( new CircleI(20) );
}
When I run this I get the following result.
./demo
Circle of radius:20 type:0
Assertion failed: type == CircleType, file demoTest.cpp, line 15
Compilation abort (core dumped) at Thu Mar 26 10:38:23
0
Comments
-
Hi John,
This is expected, because the generated Circle derives from the generated Shape with virtual inheritance.
With such virtual base class, the constructor of the most derived class needs to initialize each virtual base class, e.g. you would write:CircleI(int rad) : Shape(CircleType), Circle(CircleType, rad) { }
Otherwise, it's the default Shape constructor that gets called.
BTW if you add a third class in your Slice class hierarchy and read the generated code, you'll see that the "one-shot" constructor of the most derived class properly calls the constructor of all base classes with data members.
Best regards,
Bernard0 -
Hi Nick,
There is no way-around, as it is a consequence of mapping Slice class inheritance to virtual inheritance in C++. We've changed this mapping in the upcoming 3.4 release (to use non-virtual inheritance by default) to avoid this often surprising behavior.
Best regards,
Bernard0
