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?
Related
I have a problem with interfaces and multiple inheritance. I hope to design my program such that one update call processes a variety of objects, with each behavioral 'building block' tucked away in a single function.
For example, I'd like to move a creature from point A to B in one place, regardless of whether it must perform pre/post move actions. But, my multiple inheritance scheme fails (below, with the bug rem'd), making me think I'd need to duplicate code somewhere.
Clearly I don't understand this well enough! (but I'm working hard to learn it)
Q1. Why can't IPhysics::Move 'see' Creature::Move(), in the CreatureAirborne class?
Q2. Am I completely missing the proper usage of interfaces and/or multiple inheritance? If so, any guidance is appreciated!
#include <deque>
#include <memory>
class IGameObject
{
public:
virtual ~IGameObject() {}
virtual void Update() = 0;
};
class IPhysics
{
public:
virtual ~IPhysics() {}
virtual void Move() = 0;
};
class IPhysicsFlight : public IPhysics
{
public:
virtual ~IPhysicsFlight() {}
virtual void Land() = 0;
virtual void TakeOff() = 0;
};
class Creature : public IGameObject, IPhysics
{
protected:
virtual void Move() {}
public:
Creature() {}
virtual ~Creature() {}
virtual void Update() {}
};
class CreatureAirborne : public Creature, IPhysicsFlight
{
private:
virtual void Land() {}
virtual void TakeOff() {}
public:
CreatureAirborne() {}
virtual ~CreatureAirborne() {}
virtual void Update();
};
void CreatureAirborne::Update()
{
TakeOff();
Creature::Move();
Land();
}
int main()
{
std::deque<std::shared_ptr<Creature>> creatures;
std::shared_ptr<Creature> cow(new Creature);
creatures.push_back(cow);
// The butterfly fails to compile with 'cannot instantiate; void IPhysics::Move(void) is abstract'
// std::shared_ptr<CreatureAirborne> butterfly(new CreatureAirborne);
// creatures.push_back(butterfly);
for (auto i : creatures)
{
i->Update();
}
}
It's somewhat had to follow your hierarchy, but it looks correct evaluation on the compiler's part.
You don't have virtual inheritance anywhere, so CreatureAirborne will have duplicated base classes from some point. You will have two instances of IPhysics. Move, that is abstract from there is implemented on the Creature branch but remains abstract on IPhysicsFlight.
You can cure the situation by using virtual inheritance somewhere, or by implementing Move in descendant (say just calling the parent version where it exists).
I would look at things little differently
class CreatureAirborne : public IPhysicsFlight,Creature
While the code runs
new CreatureAirborne ()
The compiler will try to build IPhysicsFlight base class and Creature base class and the fact that IPhysics is a base class to both doesn't play any role rather than confusing.As far as compiler is concerned IPhysicsFlight is abstract and CreatureAirborne did not implement Move
The diamond issue will actually come into play when you do a
(new CreatureAirborne ())->Move()
It seems that it is good to make the virtual methods private in order to separate the interfaces for following two clients -
1. clients that instantiate an object and call the method
2. clients that derive from the class and may want to override the method.
Simply put - the first client does not need to know if a method is virtual. He will call the base class public non-virtual method which in turn will call the private virtual method. See code below for example.
Now in the case where the virtual method needs to super-message its base class' corresponding virtual method such as say a Save method - which has to pass through all virtual methods in the chain of inheritance in order to save data corresponding to each level of derivation - we have no option but to use a protected virtual method - unless there is a way to guarantee saving of data at all levels of derivation without using super messaging (there is none that I know).
I would like to know if above reasoning correct.
Make sure you use the scroll to see the entire code.
#include <iostream>
using namespace std;
class A {
string data;
protected:
virtual void SaveData()= 0;
public:
A():data("Data of A"){}
void Save(){
cout << data << endl;
SaveData();
}
};
class B : public A {
string data;
protected:
virtual void SaveData() { cout << data << endl;}
public:
B():data("Data of B") {}
};
class C : public B {
string data;
protected:
virtual void SaveData() {
B::SaveData();
cout << data << endl;
}
public:
C():data("Data of C") {}
};
int main(int argc, const char * argv[])
{
C c;
c.Save();
return 0;
}
Yes, if you need to call the SaveData of another class, it needs to be accessible from that class - so public or protected.
You are exactly right:
NVI (Non-Virtual Interface) requires that virtual methods not be public
Calling the base class method requires that it not private
therefore protected is the obvious solution, at least in C++03. Unfortunately it means you have to trust the derived class developer not to forget to call "super".
In C++11, you can use final to prevent a derived class from overriding a virtual method; it means though that you are forced to introduce a new hook, example:
class Base {
public:
void save() {
// do something
this->saveImpl();
// do something
}
private:
virtual void saveImpl() {}
};
class Child: public Base {
private:
virtual void saveImpl() final {
// do something
this->saveImpl2();
// do something
}
virtual void saveImpl2() {}
};
Of course, there is the trouble of having to come up with a new name each and every time... but at least you are guaranteed that Child::saveImpl will be called because none of its children can override it.
It's difficult to tell what you're asking, but from the example, you do not need to make the method protected. It actually can be private. For details about the subtleties see this post: What is the point of a private pure virtual function?.
So long as you're not calling the private member from derived class (or outside classes), you're ok. Overriding of private members is ok. It does sound quite naughty and wrong that you can override your parent's privates, but in c++ you're allowed to do this.
The following should be ok:
#include <iostream>
using namespace std;
class A {
string data;
private:
virtual void SaveData()= 0;
public:
A():data("Data of A"){}
void Save(){
cout << data << endl;
SaveData();
}
};
class B : public A {
string data;
private:
virtual void SaveData() { cout << data << endl;}
public:
B():data("Data of B") {}
};
Say I have a abstract base class and I want to have a pure virtual method which must be implemented by the derived class but I want to make sure that the derived method calls functions in a particular order what could I do to enforce it ?
I.E
base class
virtual void doABC()=0;
virtual void A()=0;
virtual void B()=0;
virtual void C()=0;
// must call ABC in the correct order
derived class public base
void doABC();
This is just so I have a better understanding on how to design my classes to enforce someone to use my class correctly.
You're looking for the template method pattern:
http://en.wikipedia.org/wiki/Template_method_pattern
Something along these lines:
class BaseAlgorithm
{
protected:
virtual void firstStep() = 0;
virtual void secondStep() = 0;
virtual void finalStep() = 0;
public:
void runAlgorithm()
{
firstStep();
secondStep();
finalStep();
}
};
class ConcreteAlgorithm : BaseAlgorithm
{
virtual void firstStep() {};
virtual void secondStep() {};
virtual void finalStep() {};
};
You basically force extending classes to implement all intermediate steps, but you keep them protected or private - document this - and only call runAlgorithm(), which ties the smaller pieces together.
There are actually two particular ways, depending on whether you go with inheritance or parameterization.
If you with inheritance, it is the Template Method pattern:
class Base {
public:
void doit() {
this->do1();
this->do2();
}
private:
virtual void do1() = 0;
virtual void do2() = 0;
};
And if you go with parameterization, it is the Strategy pattern:
class Strategy {
public:
virtual void do1() = 0;
virtual void do2() = 0;
};
void doit(Strategy& s) {
s.do1();
s.do2();
}
From the website:
Strategy is like Template Method except in its granularity. [Coplien, C++ Report, Mar 96, p88]
Template Method uses inheritance to vary part of an algorithm. Strategy uses delegation to vary the entire algorithm. [GoF, p330]
Strategy modifies the logic of individual objects. Template Method modifies the logic of an entire class. [Grand, p383]
I recommend you familiarize yourself with them.
The simplest answer could be if You remove virtual from doABC(), so that it can not be derived by child class. Call the virtual methods inside doABC() in correct order.
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
}
EDIT: minor fixes (virtual Print; return mpInstance) following remarks in the answers.
I am trying to create a system in which I can derive a Child class from any Base class, and its implementation should replace the implementation of the base class.
All the objects that create and use the base class objects shouldn't change the way they create or call an object, i.e. should continue calling BaseClass.Create() even when they actually create a Child class.
The Base classes know that they can be overridden, but they do not know the concrete classes that override them.
And I want the registration of all the the Child classes to be done just in one place.
Here is my implementation:
class CAbstractFactory
{
public:
virtual ~CAbstractFactory()=0;
};
template<typename Class>
class CRegisteredClassFactory: public CAbstractFactory
{
public:
~CRegisteredClassFactory(){};
Class* CreateAndGet()
{
pClass = new Class;
return pClass;
}
private:
Class* pClass;
};
// holds info about all the classes that were registered to be overridden
class CRegisteredClasses
{
public:
bool find(const string & sClassName);
CAbstractFactory* GetFactory(const string & sClassName)
{
return mRegisteredClasses[sClassName];
}
void RegisterClass(const string & sClassName, CAbstractFactory* pConcreteFactory);
private:
map<string, CAbstractFactory* > mRegisteredClasses;
};
// Here I hold the data about all the registered classes. I hold statically one object of this class.
// in this example I register a class CChildClass, which will override the implementation of CBaseClass,
// and a class CFooChildClass which will override CFooBaseClass
class RegistrationData
{
public:
void RegisterAll()
{
mRegisteredClasses.RegisterClass("CBaseClass", & mChildClassFactory);
mRegisteredClasses.RegisterClass("CFooBaseClass", & mFooChildClassFactory);
};
CRegisteredClasses* GetRegisteredClasses(){return &mRegisteredClasses;};
private:
CRegisteredClasses mRegisteredClasses;
CRegisteredClassFactory<CChildClass> mChildClassFactory;
CRegisteredClassFactory<CFooChildClass> mFooChildClassFactory;
};
static RegistrationData StaticRegistrationData;
// and here are the base class and the child class
// in the implementation of CBaseClass::Create I check, whether it should be overridden by another class.
class CBaseClass
{
public:
static CBaseClass* Create()
{
CRegisteredClasses* pRegisteredClasses = StaticRegistrationData.GetRegisteredClasses();
if (pRegisteredClasses->find("CBaseClass"))
{
CRegisteredClassFactory<CBaseClass>* pFac =
dynamic_cast<CRegisteredClassFactory<CBaseClass>* >(pRegisteredClasses->GetFactory("CBaseClass"));
mpInstance = pFac->CreateAndGet();
}
else
{
mpInstance = new CBaseClass;
}
return mpInstance;
}
virtual void Print(){cout << "Base" << endl;};
private:
static CBaseClass* mpInstance;
};
class CChildClass : public CBaseClass
{
public:
void Print(){cout << "Child" << endl;};
private:
};
Using this implementation, when I am doing this from some other class:
StaticRegistrationData.RegisterAll();
CBaseClass* b = CBaseClass::Create();
b.Print();
I expect to get "Child" in the output.
What do you think of this design? Did I complicate things too much and it can be done easier? And is it OK that I create a template that inherits from an abstract class?
I had to use dynamic_pointer (didn't compile otherwise) - is it a hint that something is wrong?
Thank you.
This sort of pattern is fairly common. I'm not a C++ expert but in Java you see this everywhere. The dynamic cast appears to be necessary because the compiler can't tell what kind of factory you've stored in the map. To my knowledge there isn't much you can do about that with the current design. It would help to know how these objects are meant to be used. Let me give you an example of how a similar task is accomplished in Java's database library (JDBC):
The system has a DriverManager which knows about JDBC drivers. The drivers have to be registered somehow (the details aren't important); once registered whenever you ask for a database connection you get a Connection object. Normally this object will be an OracleConnection or an MSSQLConnection or something similar, but the client code only sees "Connection". To get a Statement object you say connection.prepareStatement, which returns an object of type PreparedStatement; except that it's really an OraclePreparedStatement or MSSQLPreparedStatement. This is transparent to the client because the factory for Statements is in the Connection, and the factory for Connections is in the DriverManager.
If your classes are similarly related you may want to have a function that returns a specific type of class, much like DriverManager's getConnection method returns a Connection. No casting required.
The other approach you may want to consider is using a factory that has a factory-method for each specific class you need. Then you only need one factory-factory to get an instance of the Factory. Sample (sorry if this isn't proper C++):
class CClassFactory
{
public:
virtual CBaseClass* CreateBase() { return new CBaseClass(); }
virtual CFooBaseClass* CreateFoo() { return new CFooBaseClass();}
}
class CAImplClassFactory : public CClassFactory
{
public:
virtual CBaseClass* CreateBase() { return new CAImplBaseClass(); }
virtual CFooBaseClass* CreateFoo() { return new CAImplFooBaseClass();}
}
class CBImplClassFactory : public CClassFactory // only overrides one method
{
public:
virtual CBaseClass* CreateBase() { return new CBImplBaseClass(); }
}
As for the other comments criticizing the use of inheritance: in my opinion there is no difference between an interface and public inheritance; so go ahead and use classes instead of interfaces wherever it makes sense. Pure Interfaces may be more flexible in the long run but maybe not. Without more details about your class hierarchy it's impossible to say.
Usually, base class/ derived class pattern is used when you have an interface in base class, and that interface is implemented in derived class (IS-A relationship). In your case, the base class does not seem to have any connection with derived class - it may as well be void*.
If there is no connection between base class and derived class, why do you use inheritance? What is the benefit of having a factory if factory's output cannot be used in a general way? You have
class CAbstractFactory
{
public:
virtual ~CAbstractFactory()=0;
};
This is perfectly wrong. A factory has to manufacture something that can be used immediately:
class CAbstractFactory
{
public:
virtual ~CAbstractFactory(){};
public:
CBaseClass* CreateAndGet()
{
pClass = new Class;
return pClass;
}
private:
CBaseClass* pClass;
protected:
CBaseClass *create() = 0;
};
In general, you're mixing inheritance, virtual functions and templates the way they should not be mixed.
Without having read all of the code or gone into the details, it seems like you should've done the following:
make b of type CChildClass,
make CBaseClass::Print a virtual function.
Maybe I'm wrong but I didn't find any return statement in your CBaseClass::Create() method!
Personally, I think this design overuses inheritance.
"I am trying to create a system in which I can derive a Child class from any Base class, and its implementation should replace the implementation of the base class." - I don't know that IS-A relationships should be that flexible.
I wonder if you'd be better off using interfaces (pure virtual classes in C++) and mixin behavior. If I were writing it in Java I'd do this:
public interface Foo
{
void doSomething();
}
public class MixinDemo implements Foo
{
private Foo mixin;
public MixinDemo(Foo f)
{
this.mixin = f;
}
public void doSomething() { this.mixin.doSomething(); }
}
Now I can change the behavior as needed by changing the Foo implementation that I pass to the MixinDemo.