In C++, how can I create two interfaces for a class? - c++

For example, when creating a class library, I would like to specify an internal API and a public API for each classes, so I can hide some details from the user. The internal API would be used by other classes in the library, and the public API would be used by the library user.
Is it possible?

In C++, interface could mean many things. It could mean pure virtual functions that you implement in the derived classes, as in the following example,
class Interface
{
public:
virtual void f() = 0 ;
};
class Implementation : public Interface
{
public:
virtual void f() {}
};
--
Or it could mean just public functions in your class:
class A
{
public:
void f() {} //public function - an interface that the outside world can
//use to talk to your class.
};
You can use either of these and can make use of access-specifiers ( public, protected, private) to make your interfaces public or internal/private!

Kind of.
Some libraries use friend classes/functions for this. Each class declares other classes as friends if they need access to more than the "public" interface:
class Car {
friend class Mechanic;
private:
Engine engine;
};
class Mechanic {
// something involving Car::engine...
};
It's not very pretty, but it works.
Another approach that might work for you is the pimpl (pointer-to-implementation) idiom:
class CarImpl; // declaration only
class Car {
private:
CarImpl *impl;
public:
CarImpl *getImpl(); // doesn't strictly belong in the pimpl pattern
// methods that simply call the corresponding methods on impl
};
The internal interface can be accessed through a getImpl() call. You would put the CarImpl declaration in a header file that is clearly marked as internal, so clients won't access it. For example, you could put such headers in a subdirectory called internal.
The obvious drawback is that the Car class has a bunch of trivial methods that you have to implement.
A third approach, that I do not recommend, is inheritance:
class Car {
public:
virtual void start() = 0;
static Car *create();
};
And in an internal header:
class CarImpl : public Car {
public:
virtual void start();
};
The Car class only exposes the public interface; to get access to the internal interface, internal code needs to do a downcast to CarImpl. This is ugly.

You can use many tricks to grant friendship or an "extended" interface to a given few, however it is soon cumbersome.
The simplest way to separate the external interface from the internal interface... is to have two interfaces, thus two classes.
If you take a peek at the set of Design Patterns proposed by the GoF, you'll notice the Proxy pattern.
You can use this by not exposing the class to the exterior of your library, but instead exposing a Proxy, in which you wrap the class, and which only exposes a subset of its interface.
class MyClass
{
public:
void foo();
void bar();
void printDebugInfo();
void test();
};
class MyClassProxy
{
public:
MyClassProxy(std::unique_ptr<MyClass> ptr): _ptr(ptr) {}
void foo() { _ptr->foo(); }
void bar() { _ptr->bar(); }
private:
std::unique_ptr<MyClass> _ptr;
};
I personally find this design rather clean. No down-casting, No subtle inheritance trick, No friendship list longer than my arm.

I'm not quite sure what you're asking, but if you have an abstract class defined:
class Loggable { ... };
You can inherit from it privately, like this:
class User : private Loggable { ... };
The class User now has the members of Loggable, but they are private.
Please see the C++ FAQ lite.

There is a number of ways to approach this. One is runtime polymorphism:
struct widget {
virtual debug_info diagnose() = 0;
virtual void draw() = 0;
};
struct window {
virtual void draw() = 0;
};
struct view : public window, public widget {
void draw();
debug_info diagnose(); // internal
};
Or with compile-time polymorphism:
struct view {
void draw();
debug_info diagnose(); // internal
};
template<class W>
void do_it(W window)
{
widget.draw();
}
template<class W>
void diagnose_it(W widget)
{
debug_info d = widget.diagnose();
}
Another approach is to expose private members to specific functions or classes:
struct widget {
virtual void draw() = 0;
};
struct view : public widget {
friend void diagnose_widget(widget w);
void draw();
private:
debug_info diagnose();
};
// internal
debug_info diagnose_widget(widget w)
{
debug_info d = w.diagnose();
}

A C++ class has 3 levels of protection: public, protected and private. Public things are accessible to everybody, protected only to descendant -- and then for themselves and not for other descendants --, private for the class and its friend.
Thus friendship is the only way to grant more than public access to a class/function which isn't a descendant, and it grants full access, which isn't always convenient.
An heavy solution which I've used with success was to write a wrapper which was a friend of the main class, and then provided additional access to its own friends (which were the only one able to construct the wrapper). I'm not really recommending it, it is tedious, but it could be useful if you have such a need.
class Main {
public:
...
private: // but wrapped
void foo();
protected:
...
private: // and not wrapped
void bar();
};
class Wrapper {
pubic:
void foo() { wrapped.foo(); }
private:
Wrapper(Main& m) : wrapped(ma) {}
Main& wrapped;
friend void qux(Main&);
};
void qux(Main& m) {
Wrapper mwrapped(m)
mwrapped.foo();
// still can't access bar
}

Related

C++ vector of classes which implement multiple virtual classes?

I'm looking to have an vector of class instances which implement multiple virtual classes.
e.g.
// assume that all the classes here have implementations
class A
{
public:
virtual void doThing();
};
class ImplementsA
: public A
{
public:
void doThing() override;
};
class B
{
public:
virtual void doSomethingElse();
};
class ImplementsB
: public B
{
public:
void doSomethingElse() override;
};
class AB
: public A
, public B
{
public:
void doThing() override;
void doSomethingElse() override;
};
class OtherAB
: public A
, public B
{
public:
void doThing() override;
void doSomethingElse() override;
// these implementations are different than in AB
};
int main()
{
// here I'd like to have a vector of classes AB and OtherAB, and any other classes which implement both A and B
}
I've been poking around but I haven't found any information about how to do this. Is this possible in C++? If so, how would the vector be structured/initialized to allow it?
Thank you!
You need the Adapter and/or the Proxy and/or the Decorator design pattern. Try to wrap all the inheritance in ABwrapper : public A, public B
and create a vector of ABwrapper
class ABWrapper: public A, public B
{
public:
A *a; B *b; AB *ab;
void doThing()
{
if (this->ab==nullptr) {this->a->doThing(); return;}
this->ab->doThing();
}
void doOtherThing()
{
if (this->ab==nullptr) {this->b->doOtherThing(); return;}
this->ab->doOtherThing();
}
}
...
Vector<ABWrapper>
There are various ways to go about it:
Create a bundling interface, and manage your objects using pointers to them.
This runs counter to the interface-segregation-principle, and pre-supposes that you can modify all the affected classes.
Still, if you can do it and accept the drawback, it's the most efficient choice.
Save a pointer to each interesting interface.
If you need at most two interfaces, this is the second most efficient choice. Space use obviously increases linearly.
Write your own wrapper abstracting the differences away. See smart-pointer and std::function for ideas.
Use std::any and a map for registering how to access the interface. If few statically known fully derived types are involved, static functions might serve, and std::variant is enough.

Unable to access members of including class from a polymorphic nested classes

A nested class Foo::Utility has access to another nested class Foo::Container even if the later is private. I am trying to extend this access to a polymorphic version UtilityPrint of Foo::Utility without success:
class Foo {
private:
class Container {};
public:
class Utility {
public:
virtual void action(Container &) = 0;
// works even if Container is private
};
Container container;
Utility * utility;
Foo(Utility * utility): container(), utility(utility) {};
void performAction() {
utility -> action(container);
}
};
// polymorphic nested class
// failed attempt
class UtilityPrint : Foo::Utility {
public:
virtual void action(Foo::Container &) {
/* Implementation */
// this does not work, because Foo::Container is private
}
};
Is there a correct way to achieve this, or is this a bad idea to begin with?
The error message I get is this:
error: ‘class Foo::Container’ is private
class Container {};
^
error: within this context
virtual void action(Foo::Container &) {
Also, Here is my reason for using this somewhat weird design:
I wanted a container and a polymorphic utility that does things to both the container and Foo. Since both container and utility would only be used within the context of Foo, I put the two classes into Foo.
EDIT: I can wrap the derived Utility in a derived Foo, and the code compiles:
class Foo {
protected:
class Container {};
public:
class Utility {
public:
virtual void action(Container &) = 0;
};
Container container;
Utility * utility;
Foo(Utility * utility): container(), utility(utility) {};
void performAction() {
utility -> action(container);
}
};
class FooPrint : public Foo {
public:
class Utility : Foo::Utility {
public:
virtual void action(Foo::Container &) {
/* Implementation */
}
};
};
This however introduces a wrapper class FooPrint which exists only for syntactic reasons and is (being a derived class!) never meant to be instantiated. I don't like this approach for this reason, but I can be very wrong on this regard.
Access is not inherited. This is more often brought up when discussing friends, but it applies here as well.
First, let's look at why Foo::Utility::action can access the private class Foo::Container. Actually, it's right there in the names. The Foo::Container can only be accessed by members of Foo, and members of Foo can be recognized when you write out their qualified names and that name starts with "Foo::".
In contrast, UtilityPrint is not a member of Foo. (In fact, it would be a huge security violation if someone could simply say "oh, yeah, I'm a member too!" and get access to your private information.) So while UtilityPrint has (protected) access to Foo::Utility, it does not have access to everything to which Foo::Utility has access.
If Foo::Utility desires to extend its access to classes derived from it, it would need to explicitly do so. One way to do this is by creating an alias.
class Utility {
protected:
using Container = Foo::Container; // Derived classes can access this.
public:
virtual void action(Container &) = 0;
virtual ~Utility() {} // <-- remember to properly support polymorphism
};
That still leaves open the question of whether or not this is good design. I would consider this a warning flag that something might be off, but not conclusively so. The question does not have enough context for me to make this sort of call. I would just give you the guideline that if you feel like you are circumventing a lot of language features (like private access), then maybe the design needs work.
I adopted this solution:
class Foo {
protected:
class Container {};
public:
class Utility {
protected:
typedef Container FooContainer;
public:
virtual void action(Container &) = 0;
};
Container container;
Utility * utility;
Foo(Utility * utility): container(), utility(utility) {};
void performAction() {
utility -> action(container);
}
};
class UtilityPrint : Foo::Utility {
public:
virtual void action(FooContainer &) {
/* implementation */
}
};
When the name FooContainer is introduced using typedef, accessibility is applied to that name only, with no regard of it actually referring to Foo::Container. This allows all derived Utility to reference Foo::Container by naming FooContainer.
I believe this also applies to using

Factory pattern with private constructors in C++

I am trying to implement a factory pattern that consists of
a factory class
an abstract class with protected constructor
inherited classes with private constructors and virtual public
destructors.
I want to make sure that
No other one than the factory can not create any instance
If a new inherited class is defined it will not require any modification on interface class and already defined inherited classes. Juts new class implementation and adding into factory classes create method.
I also do not want to write same-like code(like static factory method per inited) for every inherited class and leave the future developers much work for factory connections.
i.e with pseduo code
class Factory;
class Interface
{
protected:
Interface(){/*Do something*/};
public:
virtual ~Interface(){/*Do something*/}
/*I wish I could do below and it is valid for all inherited
classes but friendship is not inherited in C++*/
//friend Interface* Factory::create(Type)
};
class InheritedA:public Interface
{
private:
InheritedA(){/*Do something*/};
public:
virtual ~InheritedA(){/*Do something*/}
/*I dont want to do below two lines for every inherited class*/
//friend Interface Factory::create(Type)
//public: Interface* factoryInheritedA(){return new InheritedA();}
};
class InheritedB:public Interface
{
private:
InheritedB(){/*Do something*/};
public:
virtual ~InheritedA(){/*Do something*/}
};
class Factory
{
static Interface* create(Interface type)
{
switch(type)
{
case A:
return new InheritedA();
case B:
return new InheritedB();
default:
//exceptions etc
}
}
}
int main()
{
Interface* I = Factory::create(A/*or B*/);
return 0;
}
Above code is the cloest I put out. Any suggestions (a speciality of C++, a different design,...) is welcome.
I don't think this a good idea, but here is a way to do this. You create a Tag type which can only be created by the Factory and make all the constructors take a parameter of that type.
class Factory;
class Tag
{
Tag() {}
friend Factory;
};
class Interface
{
public:
Interface(Tag t) {}
virtual ~Interface() {}
};
struct Impl1: public Interface
{
Impl1(Tag t): Interface(t) {}
};
class Factory
{
public:
Interface* makeInstance()
{
return new Impl1( Tag{} );
}
};
void foo()
{
Impl1 i( Tag{} );
}
You will get a compiler error in foo() because Tag::Tag is private.
You could have a templated function:
template<typename Type>
std::unique_ptr<Interface> make_interface() {
// exceptions etc..
}
template<>
std::unique_ptr<Interface> make_interface<InheritedA>() {
return std::make_unique<InheritedA>();
}
template<>
std::unique_ptr<Interface> make_interface<InheritedB>() {
return std::make_unique<InheritedB>();
}
but I really don't see the point in all of this Javaesque boilerplate. Not to mention that you are transforming a compile time information (the type) into a runtime one (via exceptions) for no reason really.
I would just go with:
std::unique_ptr<Interface> ptr_a = std::make_unique<InheritedA>();
std::unique_ptr<Interface> ptr_b = std::make_unique<InheritedB>();
when needed.
It is rarely a good practice to use Factory. I count it as an anti-pattern together with the Singleton. In good design, classess do not concern themselves on how they are created. In your case, when used in Factory, how do you create your class using custom allocator? On stack? In shared memory? In memory-mapped file? From the buffer? In place? This is all really hard to cover in Factory, but do not despair - the simple and elegant solution is ditch the factory!

Contravariant types and extensibility

I'm writing a C++ library for optimization, and I've encountered a curious issue with contra-variant types.
So, I define a hierarchy of "functions", based on what information they can compute.
class Function {
public:
double value()=0;
}
class DifferentiableFunction : public Function {
public:
const double* gradient()=0;
}
class TwiceDifferentiableFunction : public DifferentiableFunction {
public:
const double* hessian()=0;
}
Which is all well and good, but now I want to define interfaces for the optimizers. For example, some optimizers require gradient information, or hessian information in order to optimize, and some don't. So the types of the optimizers are contravariant to the types of the functions.
class HessianOptimizer {
public:
set_function(TwiceDifferentiableFunction* f)=0;
}
class GradientOptimizer : public HessianOptimizer {
public:
set_function(DifferentiableFunction* f)=0;
}
class Optimizer: public GradientOptimizer {
public:
set_function(TwiceDifferentiableFunction* f)=0;
}
Which I suppose makes sense from a type theoretic perspective, but the thing that is weird about it is that usually when people want to extend code, they will inherit the already existing classes. So for example, if someone else was using this library, and they wanted to create a new type of optimizer that requires more information than the hessian, they might create a class like
class ThriceDifferentiableFunction: public TwiceDifferentiableFunction }
public:
const double* thirdderivative()=0;
}
But then to create the corresponding optimizer class, we would have to make HessianOptimizer extend ThirdOrderOptimizer. But the library user would have to modify the library to do so! So while we can add on the ThriceDifferentiableFunction without having to modify the library, it seems like the contravariant types lose this property. This seems to just be an artifact of the fact the classes declare their parent types rather than their children types.
But how are you supposed to deal with this? Is there any way to do it nicely?
Since they're just interfaces, you don't have to be afraid of multiple inheritance with them. Why not make the optimiser types siblings instead of descendants?
class OptimizerBase
{
// Common stuff goes here
};
class HessianOptimizer : virtual public OptimizerBase {
public:
virtual set_function(TwiceDifferentiableFunction* f)=0;
}
class GradientOptimizer : virtual public OptimizerBase {
public:
virtual set_function(DifferentiableFunction* f)=0;
}
class Optimizer : virtual public OptimizerBase {
public:
virtual set_function(TwiceDifferentiableFunction* f)=0;
}
// impl
class MyGradientOptimizer : virtual public GradientOptimizer, virtual public HessianOptimizer
{
// ...
};

Restricting method call to another method

There probably is a fairly simple and straight-forward answer for this, but for some reason I can't see it.
I need to restrict calling methods from a class only to some methods implemented by derived classes of some interface.
Say I have
class A{
public:
static void foo();
};
class myInterface{
public:
virtual void onlyCallFooFromHere() = 0;
}
class myImplementation : public myInterface{
public:
virtual void onlyCallFooFromHere()
{
A::foo(); //this should work
}
void otherFoo()
{
A::foo(); //i want to get a compilation error here
}
}
So I should be able to call A::foo only from the method onlyCallFooFromHere()
Is there a way to achieve this? I'm open to any suggestions, including changing the class design.
EDIT:
So... I feel there's a need to further explain the issue. I have a utility class which interacts with a database (mainly updates records) - class A.
In my interface (which represents a basic database objects) I have the virtual function updateRecord() from which I call methods from the db utility class. I want to enforce updating the database only in the updateRecord() function of all extending classes and nowhere else. I don't believe this to be a bad design choice, even if not possible. However, if indeed not possible, I would appreciate a different solution.
Change the class design - what you want is impossible.
I am unsure of what you are trying to achieve with so little details and I am unable to comment further.
[Disclaimer: this solution will stop Murphy, not Macchiavelli.]
How about:
class DatabaseQueryInterface {
public:
~virtual DatabseQueryInterface() = 0;
virtual Query compileQuery() const = 0; // or whatever
virtual ResultSet runQuery(const Query&) const = 0; // etc
};
class DatabaseUpdateInterface : public DatabaseQueryInterface {
public:
virtual Update compileUpdate() const = 0; // whatever
};
class DatabaseObject {
public:
virtual ~DatabaseObject() = 0;
protected:
virtual void queryRecord(const DatabaseQueryInterface& interface) = 0;
virtual void updateRecord(const DatabaseUpdateInterface& interface) = 0;
};
class SomeConcreteDatabaseObject : public DatabaseObject {
protected:
virtual void updateRecord(const DatabaseUpdateInterface& interface) {
// gets to use interface->compileUpdate()
}
virtual void queryRecord(const DatabaseQueryInterface& interface) {
// only gets query methods, no updates
}
};
So the basic idea is that your DatabaseObject base class squirrels away a private Query object and a private Update object and when it comes time to call the protected members of the subclass it hands off the Update interface to the updateRecord() method, and the Query interface to the queryRecord() method.
That way the natural thing for the subclasses is to use the object they are passed to talk to the database. Of course they can always resort to dirty tricks to store away a passed-in Update object and try to use it later from a query method, but frankly if they go to such lengths, they're on their own.
You could split your project into different TUs:
// A.h
class A
{
public:
static void foo();
};
// My.h
class myInterface
{
public:
virtual void onlyCallFooFromHere() = 0;
}
class myImplementation : public myInterface
{
public:
virtual void onlyCallFooFromHere();
void otherFoo();
};
// My-with-A.cpp
#include "My.h"
#include "A.h"
void myImplementation::onlyCallFooFromHere() { /* use A */ }
// My-without-A.cpp
#include "My.h"
void myImplementation::otherFoo() { /* no A here */ }
You probably know this, but with inheritance, you can have public, protected, and private member access.
If a member is private in the base class, the derived cannot access it, while if that same member is protected, then the derived class can access it (while it still isn't public, so you're maintaining encapsulation).
There's no way to stop specific functions from being able to see whats available in their scope though (which is what you're asking), but you can design your base class so that the derived classes can only access specific elements of it.
This could be useful because class B could inherit from class A as protected (thus getting its protected members) while class C could inherit from the same class A as public (thus not getting access to its protected members). This will let you get some form of call availability difference at least -- between classes though, not between functions in the same class.
This could work.
class myInterface;
class A {
private:
friend class myInterface;
static void foo();
};
class myInterface {
public:
virtual void onlyCallFooFromHere() {callFoo();}
protected:
void callFoo() {A::foo();}
};
Though at this point I think I'd just make A::foo a static of myInterface. The concerns aren't really separate anymore.
class myInterface {
protected:
static void foo();
};
Is there a reason foo is in A?