-6

I'm writing a C++ library which needs to creates a complex object (D), but return to the user of my library a pointer to a simplified object (B) (hiding many of the methods of the complex object). I have decided to implement this by returning a pointer to a simplified base class (B), and adding all of my complex functionality to a derived class (D) as follows:

class B {
  virtual void simple() = 0;
}

class D : public B {
  void simple() { cout << "visible simple stuff" ; }
  void complex() { cout << "invisible complex stuff" ; }
}

Internally I create my object D, but I return an upcast pointer as follows:

D Derived;
B *Bptr = &Derived;
return Bptr;
  1. Is this the right way to hide functionality from the user, while making all of the additional functionality visible within the library?

  2. Is hiding the .h file for class D the only way to prevent my library users from accessing the D methods? (Downcasting back to a D class) I will be releaseing the library as open source, so the user of the library could access the D class definition.

TSG
  • 4,242
  • 9
  • 61
  • 121
  • User can only see `B` then the methods need to be pure virtual methods of `B` and implemented in `D`. Look up _"interface"_ classes for C++. – Richard Critten Dec 27 '17 at 13:12
  • 3
    _"I'm confused about what happens when a user of my library attempts:"_ Why be confused, when you can just pretend to be such a user, and test/answer your questions for yourself? You would quickly find that calling methods of `D` on a `B` is a syntax error, if it wasn't already obvious. And if you wanted these to be `virtual` methods, the result would be obvious from the basic rules of how virtual functions (must) work. I don't feel this question demonstrates sufficient basic research to be useful. – underscore_d Dec 27 '17 at 13:13
  • If you don’t allocate D on free store use a reference instead of a pointer a return value. If you allocate it on the free store use a unique_ptr. –  Dec 27 '17 at 13:21
  • I was looking for a deeper discussion (not yes it compiles) - I've rephrased – TSG Dec 27 '17 at 13:21
  • `Is hiding the .h file for class D` why do you have a .h file? –  Dec 27 '17 at 13:23
  • mani66: How does a unique_ptr protect the complex methods of D? I have a .h for D because it is one of the classes inside my library. – TSG Dec 27 '17 at 13:25
  • @TSG "I was looking for a deeper discussion" And, yet, SO is not a forum, so "questions" that asks for discussions are off-topic. – Algirdas Preidžius Dec 27 '17 at 13:55

1 Answers1

0

About question #1: yes, if you provide a factory method along with your 'simple' interface:

class B {
public:
    static B * create();
    virtual void simple() = 0;
};

in B's implementation file (cpp):

B *B::create()
{
    return new D(); //or whatever 'hidden' implementation 
}

About your #2: hiding functionality means simplification in the first place, and is intended as a favour toward the library users, not a punishing constraint. So, hide the D class entirely and let the (good) users be happy with it.

p-a-o-l-o
  • 9,807
  • 2
  • 22
  • 35
  • Very cool - I didn't know B could create a D. Since the factory returns a D object is it automatically upcast to a B ? – TSG Dec 27 '17 at 15:39
  • Yes it is. A pointer to B is all users can see, they know nothing about D (and don't want to know, trust me). – p-a-o-l-o Dec 27 '17 at 15:41