Member Function Pointers and Binding

Function Pointers with Abstract Base Classes

Can we use member function pointers with abstract base classes and derived classes?

Abstract art representing computer programming

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:

Pointing to Abstract Base Class Functions

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;
}

Using with Derived Classes

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

Storing in Data Structures

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

Limitations and Considerations

  • You cannot create an instance of an abstract base class, so you'll always be using these pointers with derived class objects.
  • Be cautious when using pointers to pure virtual functions. While you can create such pointers, attempting to call a pure virtual function through a base class pointer will result in undefined behavior if the function hasn't been overridden.
  • When using multiple inheritance, be aware of potential ambiguities and use explicit casting if necessary.

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.

sdl2-promo.jpg
Part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, unlimited access

This course includes:

  • 55 Lessons
  • 100+ Code Samples
  • 91% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved