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
Comprehensive course covering advanced concepts, and how to use them on large-scale projects.
View Course