Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

questions about an article introducing C++ interface

I have been reading an article about C++ interfaces (http://accu.org/index.php/journals/233) and I am completely lost at the part where it says all the virtual member functions should be made private (the section titled "Strengthening the Separation"). It just does not make sense to me at all.

According to the author, the code is like this:

class shape {
public:
  virtual ~shape();
  virtual void move_x(distance x) = 0;
  virtual void move_y(distance y) = 0;
  virtual void rotate(angle rotation) = 0;
  //...
};

class line : public shape {
public:
  line(point end_point_1, point end_point_2);
  //...
private:
  virtual ~line();
  virtual void move_x(distance x);
  virtual void move_y(distance y);
  virtual void rotate(angle rotation);
  //...
};

So we have a pure virtual function which is public, and its implementation (in the line class) which is private.

Could anybody explain how the move_x function can be called? Its access specifier is private, it will lead to an error if I try to do this:

line my_line(point(0,0), point(1,2));
my_line.move_x(-1); // does not compile

Similarly is it correct to say that the drawing interface (see earlier in the article)cannot access these functions either?

Thank you.

like image 837
Andy Avatar asked Jan 28 '10 09:01

Andy


3 Answers

The idea is that you'd use those methods via a reference or pointer to shape.

shape &s = my_line;
s.move_x(-1);

This could be justified on the grounds of "reveal only what you need to", or as a form of self-documentation. It proves that the methods are only called in the intended way.

like image 154
Daniel Earwicker Avatar answered Nov 15 '22 09:11

Daniel Earwicker


If you have in instance of the line object, you might be tempted to call it's methods. But if the only way you can get at them is by asking for it's shape interface, then the object looks to less like an object and more like a collection of interfaces.

This makes more sense if you imagine line implementing more than one interface.

like image 25
John Knoeller Avatar answered Nov 15 '22 09:11

John Knoeller


This advice is applicable to homogeneous hierarchies only -- that is, hierarchies in which derived classes introduce no new functions (except constructors maybe) and just override base class functions. In this case you obviously don't need to work with line instance directly -- only via pointer/reference to shape.

When you have less homogeneous hierarchy, this advice hasn't much sense: how would anyone apply it to cases when derived class introduces new functions, or inherits them from another base class? In this case you sometimes want to work directly with objects of derived class directly, and this advice would lead to inconveniences only.

Further development of this idea -- less radical and usable in more contexts -- Non-Virtual Interface (NVI) by Herb Sutter.

like image 43
Alexander Poluektov Avatar answered Nov 15 '22 09:11

Alexander Poluektov