Yes, you can use member function pointers with abstract base classes and derived classes in C++. This capability is particularly useful for implementing polymorphic behavior and designing flexible, extensible systems.
Here's how it works, along with some important considerations:
You can create pointers to both pure virtual and non-pure virtual functions of an abstract base class:
#include <iostream>
class Shape {
public:
// Pure virtual
virtual double area() const = 0;
virtual void draw() const {
std::cout << "Drawing a shape\n";
}
};
int main() {
double (Shape::*areaPtr)() const =
&Shape::area;
void (Shape::*drawPtr)() const =
&Shape::draw;
}
These pointers can be used with objects of derived classes, preserving polymorphic behavior:
#include <iostream>
class Shape {/*...*/};
class Circle : public Shape {
public:
Circle(double r) : radius(r) {}
double area() const override {
return 3.14159 * radius * radius;
}
void draw() const override {
std::cout << "Drawing a circle\n";
}
private:
double radius;
};
class Rectangle : public Shape {
public:
Rectangle(double w, double h) : width(w),
height(h) {}
double area() const override {
return width * height;
}
void draw() const override {
std::cout << "Drawing a rectangle\n";
}
private:
double width, height;
};
int main() {
double (Shape::*areaPtr)() const = &
Shape::area;
void (Shape::*drawPtr)() const = &Shape::draw;
Circle c(5);
Rectangle r(3, 4);
Shape* shapes[] = {&c, &r};
for (const auto& shape : shapes) {
std::cout << "Area: " << (shape->*areaPtr)()
<< '\n';
(shape->*drawPtr)();
}
}
Area: 78.5397
Drawing a circle
Area: 12
Drawing a rectangle
std::function
and std::mem_fn()
These utilities work well with abstract base classes and derived classes:
#include <functional>
#include <iostream>
class Shape {/*...*/};
class Circle : public Shape {/*...*/};
class Rectangle : public Shape {/*...*/};
int main() {
std::function<double(const Shape&)> areaFunc =
&Shape::area;
std::function<void(const Shape&)> drawFunc = &
Shape::draw;
Circle c(5);
Rectangle r(3, 4);
std::cout << "Circle area: " << areaFunc(c)
<< "\nRectangle area: " << areaFunc(r);
drawFunc(c);
drawFunc(r);
}
Circle area: 78.5397
Rectangle area: 12
Drawing a circle
Drawing a rectangle
You can store these function pointers in data structures for dynamic dispatch:
#include <functional>
#include <vector>
#include <functional>
#include <iostream>
class Shape {/*...*/};
class Circle : public Shape {/*...*/};
class Rectangle : public Shape {/*...*/};
struct ShapeOperation {
std::string name;
std::function<void(const Shape&)> operation;
};
int main() {
std::vector<ShapeOperation> operations = {
{
"Calculate Area",
[](const Shape& s){
std::cout << "Area: " << s.area() <<
'\n';
}},
{"Draw", [](const Shape& s){ s.draw(); }}};
Circle c(5);
for (const auto& op : operations) {
std::cout << op.name << ": ";
op.operation(c);
}
}
Calculate Area: Area: 78.5397
Draw: Drawing a circle
Using member function pointers with abstract base classes and derived classes allows for powerful, flexible designs in C++.
It enables you to work with objects polymorphically, create generic algorithms that operate on a variety of shapes (or other hierarchies), and implement plugin systems or callback mechanisms that can work with any class derived from a common abstract base.
Answers to questions are automatically generated and may not have been reviewed.
Explore advanced techniques for working with class member functions