...
So, trying to use a pointer-to-member operator to access a non-existent member leads to undefined behavior and must be avoided.
Non-Compliant Code Example
In this non-compliant code example there is an abstract base class Shape
and a derived class Circle
that contains a member function area
. The last line of the code following the class definitions results in undefined behavior because there is no member function corresponding to area()
in the class Shape
.
Code Block | ||
---|---|---|
| ||
class Shape { // abstract
// ...
public:
virtual void draw() = 0;
// ...
};
class Circle : public Shape {
double radius;
public:
Circle(double new_radius) : radius(new_radius) {}
void draw() {
// ...
}
virtual double area() {
return PI*radius*radius;
}
};
// ...
Shape *circ = new Circle(2.0);
double(Shape::*circ_area)() = static_cast<double(Shape::*)()>(&Circle::area);
cout << "Area: " << (circ->*circ_area)() << endl;
|
Compliant Solution (Modifiable Base Class)
If the developer is able to change the base class when it is realized that the area()
method is required in the derived class, then a pure virtual area()
method should be added to the class Shape
:
Code Block | ||
---|---|---|
| ||
class Shape { // abstract
// ...
public:
virtual void draw() = 0;
virtual void area() = 0;
// ...
}
|
Compliant Solution (Non-modifiable Base Class)
In many cases, the base class is not modifiable. In this case, one must call the derived method directly.
Code Block | ||
---|---|---|
| ||
Circle *circ = new Circle(2.0);
cout << "Area: " << (circ->area)() << endl;
|
Risk Assessment
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
OBJ38-CPP | Medium | Probable | Medium | P8 | L2 |
Bibliography
[ISO/IEC 14882-2003] Section 5.5 "Pointer-to-member operators"
...