I provide a SDK to my users, allowing them to write DLLs in C++ for expanding the software.
The SDK headers mostly contain interface class definitions. These class are of two types:
Some that the user must subclass and implement
Some that are wrappers to core classes, passed by the app to the DLL functions as pointers, which can then be used as arguments by the DLL code for calling core functions. These interfaces should not be subclassed by the user and passed to the core functions, as they expect a specific core subclass.
I write in the manual the interfaces that should not be subclassed, and only used through pointers on objects provided by the app. But at some places, it's too tempting to subclass them in the SDK if you do not read the manual.
Would it be possible to prevent subclassing some interfaces in the SDK headers?
As long as the client doesn't need to use the pointer for anything but
passing it back into your DLL, you can just use a forward declaration;
you can't derive from an incomplete type. (When faced with a similar
case recently, I went whole hog, and designed a special wrapper type
based on void*. There's a lot of casting in the interface code, but
there's no way the client can do much other than pass the value back to
me.)
If the classes in question implement an interface which the client must
also use, there are two solutions. The first is to change this,
replacing each of the member functions with a free function which takes
a pointer to the type, and just provide a forward declaration. The
second is to use something like:
class InternallyVisibleInterface;
class ClientVisibleInterface
{
private:
virtual void doSomething() = 0;
ClientVisibleInterface() = default;
friend class InternallyVisibleInterface;
protected: // Or public, depending on whether the client should
// be able to delete instances or not.
virtual ~ClientVisibleInterface() = default;
public:
void something();
};
and in your DLL:
class InternallyVisibleInterface : public ClientVisibleInterface
{
protected:
InternallyVisibleInterface() {}
// And anything else you need. If there is only one class in
// your application which should derive from the interface,
// this is it. If there are several, they should derive from
// this class, rather than ClientVisibleInterface, since this
// is the only class which can construct the
// ClientVisibleInterface base class.
};
void ClientVisibleInterface::something()
{
assert( dynamic_cast<InternallyVisibleInterface*>( this ) != nullptr );
doSomething();
}
This offers two levels of protection: first, although derivation
directly from ClientVisibleInterface is possible, it's impossible for
the resulting class to have a constructor, and so it cannot be
instantiated. And secondly, if the client code does cheat somehow,
there will be a runtime error if he does so.
You probably don't need both protections; one or the other should
suffice. The private constructor will result in a compile time error,
rather than a runtime one. On the other hand, without it, you don't
even have to mention the name of InternallyVisibleInterface in the
distributed headers.
As soon as a developper has a developpement environment, he can do almost anything, and you should not even try to control that.
IMHO the best you can do is to identify the limit between the core application and the extension DLLs and ensure that objects received from those DLLs are or correct class, and abort with a distinctive message if they are not.
Using RTTI and typeid is generally frowned upon because it is generally the sign of a bad OOP design : in normal use case, calling virtual method is enough to have proper code invoked. But I think it can safely be considered in your use case.
Related
I need to create simulation of parabolic flight of bullet(simple rectangle), and one of conditions is to make all calculation inside self-made library and to create for it interface(abstract class).
Am confused how to implement this:
Make fully abstract class and couple of functions(not methods in
class) that will use class through "get()" and "set()"?
Make class with all calculations implemented in his methods, and just
make one "draw" method pure virtual?
I'm using WinAPI, and all graphics through GDI
and will be really appreciate for any help
One of the purposes you create classes for is to separate all unrelative data and operations to the different classes.
In your case one part is calculations and the other part is result layout.
So, the best way to implement it is to define a class which provides all calculations and access to results and implement the drawing function, which will use the object of your calculation class.
Thus, it will be able to use your calculations in other environment (for example, in some your other project) without any code changing, which is natural. It will provide portability of your platform-independent caclulation code.
And the layout part, which is platform-dependent, should be implemented separatly, using just interface, which is provided by the calculation class.
class Trajectory
{
public:
// Constructor, computation call methods
// "GetResult()" function,
// which will return trajectory in the way you choose
...
private:
// computation functions
};
// somewhere else
void DrawTrajectory(Trajectory t)
{
// here is a place for calling all winapi functions
// with data you get using t.GetResult()
}
If abstract class is required you should inherit Trajectory class from an abstract class,
where you will define all functions you have to call.
In this case
//
class ITrajectory
{
public:
// virtual /type/ GetResult() = 0;
// virtual /other methods/
};
class Trajectory : public ITrajectory
{
// the same as in previous definition
};
void DrawTrajectory(ITrajectory T)
{
// the same as in previous definition
}
When you are talking about Windows, libraries, and abstract classes as interfaces, I wonder if you are thinking of sharing classes between DLLs.
There is a declspec(dllexport) keyword, but using this on classes and/or class members is bad. You end up with all your library code closely coupled and completely dependent on using the same compiler version and settings for everything.
A much better option, which allows you to upgrade compiler for one DLL at a time, for instance, is to pass interface pointers. The key here is that the consumer of the library knows nothing about the class layout. The interface doesn't describe data members or non-virtual functions which might get inlined. Only public virtual functions appear in the interface, which is just a class defined in the public header.
The DLL has the real implementation which inherits from the interface. All the consumer has is the virtual function table and a factory (plain old C-compatible function) which returns a pointer to a new object.
If you do that, you can change the implementation any way you like without changing the binary interface which consumers depend on, so they continue to work without a recompile. This is the basis of how COM objects work in Windows.
This is not a question about how they work and declared, this I think is pretty much clear to me. The question is about why to implement this?
I suppose the practical reason is to simplify bunch of other code to relate and declare their variables of base type, to handle objects and their specific methods from many other subclasses?
Could this be done by templating and typechecking, like I do it in Objective C? If so, what is more efficient? I find it confusing to declare object as one class and instantiate it as another, even if it is its child.
SOrry for stupid questions, but I havent done any real projects in C++ yet and since I am active Objective C developer (it is much smaller language thus relying heavily on SDK's functionalities, like OSX, iOS) I need to have clear view on any parallel ways of both cousins.
Yes, this can be done with templates, but then the caller must know what the actual type of the object is (the concrete class) and this increases coupling.
With virtual functions the caller doesn't need to know the actual class - it operates through a pointer to a base class, so you can compile the client once and the implementor can change the actual implementation as much as it wants and the client doesn't have to know about that as long as the interface is unchanged.
Virtual functions implement polymorphism. I don't know Obj-C, so I cannot compare both, but the motivating use case is that you can use derived objects in place of base objects and the code will work. If you have a compiled and working function foo that operates on a reference to base you need not modify it to have it work with an instance of derived.
You could do that (assuming that you had runtime type information) by obtaining the real type of the argument and then dispatching directly to the appropriate function with a switch of shorts, but that would require either manually modifying the switch for each new type (high maintenance cost) or having reflection (unavailable in C++) to obtain the method pointer. Even then, after obtaining a method pointer you would have to call it, which is as expensive as the virtual call.
As to the cost associated to a virtual call, basically (in all implementations with a virtual method table) a call to a virtual function foo applied on object o: o.foo() is translated to o.vptr[ 3 ](), where 3 is the position of foo in the virtual table, and that is a compile time constant. This basically is a double indirection:
From the object o obtain the pointer to the vtable, index that table to obtain the pointer to the function and then call. The extra cost compared with a direct non-polymorphic call is just the table lookup. (In fact there can be other hidden costs when using multiple inheritance, as the implicit this pointer might have to be shifted), but the cost of the virtual dispatch is very small.
I don't know the first thing about Objective-C, but here's why you want to "declare an object as one class and instantiate it as another": the Liskov Substitution Principle.
Since a PDF is a document, and an OpenOffice.org document is a document, and a Word Document is a document, it's quite natural to write
Document *d;
if (ends_with(filename, ".pdf"))
d = new PdfDocument(filename);
else if (ends_with(filename, ".doc"))
d = new WordDocument(filename);
else
// you get the point
d->print();
Now, for this to work, print would have to be virtual, or be implemented using virtual functions, or be implemented using a crude hack that reinvents the virtual wheel. The program need to know at runtime which of various print methods to apply.
Templating solves a different problem, where you determine at compile time which of the various containers you're going to use (for example) when you want to store a bunch of elements. If you operate on those containers with template functions, then you don't need to rewrite them when you switch containers, or add another container to your program.
A virtual function is important in inheritance. Think of an example where you have a CMonster class and then a CRaidBoss and CBoss class that inherit from CMonster.
Both need to be drawn. A CMonster has a Draw() function, but the way a CRaidBoss and a CBoss are drawn is different. Thus, the implementation is left to them by utilizing the virtual function Draw.
Well, the idea is simply to allow the compiler to perform checks for you.
It's like a lot of features : ways to hide what you don't want to have to do yourself. That's abstraction.
Inheritance, interfaces, etc. allow you to provide an interface to the compiler for the implementation code to match.
If you didn't have the virtual function mecanism, you would have to write :
class A
{
void do_something();
};
class B : public A
{
void do_something(); // this one "hide" the A::do_something(), it replace it.
};
void DoSomething( A* object )
{
// calling object->do_something will ALWAYS call A::do_something()
// that's not what you want if object is B...
// so we have to check manually:
B* b_object = dynamic_cast<B*>( object );
if( b_object != NULL ) // ok it's a b object, call B::do_something();
{
b_object->do_something()
}
else
{
object->do_something(); // that's a A, call A::do_something();
}
}
Here there are several problems :
you have to write this for each function redefined in a class hierarchy.
you have one additional if for each child class.
you have to touch this function again each time you add a definition to the whole hierarcy.
it's visible code, you can get it wrong easily, each time
So, marking functions virtual does this correctly in an implicit way, rerouting automatically, in a dynamic way, the function call to the correct implementation, depending on the final type of the object.
You dont' have to write any logic so you can't get errors in this code and have an additional thing to worry about.
It's the kind of thing you don't want to bother with as it can be done by the compiler/runtime.
The use of templates is also technically known as polymorphism from theorists. Yep, both are valid approach to the problem. The implementation technics employed will explain better or worse performance for them.
For example, Java implements templates, but through template erasure. This means that it is only apparently using templates, under the surface is plain old polymorphism.
C++ has very powerful templates. The use of templates makes code quicker, though each use of a template instantiates it for the given type. This means that, if you use an std::vector for ints, doubles and strings, you'll have three different vector classes: this means that the size of the executable will suffer.
I am relatively new to "design patterns" as they are referred to in a formal sense. I've not been a professional for very long, so I'm pretty new to this.
We've got a pure virtual interface base class. This interface class is obviously to provide the definition of what functionality its derived children are supposed to do. The current use and situation in the software dictates what type of derived child we want to use, so I recommended creating a wrapper that will communicate which type of derived child we want and return a Base pointer that points to a new derived object. This wrapper, to my understanding, is a factory.
Well, a colleague of mine created a static function in the Base class to act as the factory. This causes me trouble for two reasons. First, it seems to break the interface nature of the Base class. It feels wrong to me that the interface would itself need to have knowledge of the children derived from it.
Secondly, it causes more problems when I try to re-use the Base class across two different Qt projects. One project is where I am implementing the first (and probably only real implementation for this one class... though i want to use the same method for two other features that will have several different derived classes) derived class and the second is the actual application where my code will eventually be used. My colleague has created a derived class to act as a tester for the real application while I code my part. This means that I've got to add his headers and cpp files to my project, and that just seems wrong since I'm not even using his code for the project while I implement my part (but he will use mine when it is finished).
Am I correct in thinking that the factory really needs to be a wrapper around the Base class rather than the Base acting as the factory?
You do NOT want to use your interface class as the factory class. For one, if it is a true interface class, there is no implementation. Second, if the interface class does have some implementation defined (in addition to the pure virtual functions), making a static factory method now forces the base class to be recompiled every time you add a child class implementation.
The best way to implement the factory pattern is to have your interface class separate from your factory.
A very simple (and incomplete) example is below:
class MyInterface
{
public:
virtual void MyFunc() = 0;
};
class MyImplementation : public MyInterface
{
public:
virtual void MyFunc() {}
};
class MyFactory
{
public:
static MyInterface* CreateImplementation(...);
};
I'd have to agree with you. Probably one of the most important principles of object oriented programming is to have a single responsibility for the scope of a piece of code (whether it's a method, class or namespace). In your case, your base class serves the purpose of defining an interface. Adding a factory method to that class, violates that principle, opening the door to a world of shi... trouble.
Yes, a static factory method in the interface (base class) requires it to have knowledge of all possible instantiations. That way, you don't get any of the flexibility the Factory Method pattern is intended to bring.
The Factory should be an independent piece of code, used by client code to create instances. You have to decide somewhere in your program what concrete instance to create. Factory Method allows you to avoid having the same decision spread out through your client code. If later you want to change the implementation (or e.g. for testing), you have just one place to edit: this may be e.g. a simple global change, through conditional compilation (usually for tests), or even via a dependency injection configuration file.
Be careful about how client code communicates what kind of implementation it wants: that's not an uncommon way of reintroducing the dependencies factories are meant to hide.
It's not uncommon to see factory member functions in a class, but it makes my eyes bleed. Often their use have been mixed up with the functionality of the named constructor idiom. Moving the creation function(s) to a separate factory class will buy you more flexibility also to swap factories during testing.
When the interface is just for hiding the implementation details and there will be only one implementation of the Base interface ever, it could be ok to couple them. In that case, the factory function is just a new name for the constructor of the actual implementation.
However, that case is rare. Except when explicit designed having only one implementation ever, you are better off to assume that multiple implementations will exist at some point in time, if only for testing (as you discovered).
So usually it is better to split the Factory part into a separate class.
I have code that's meant to manage operations on both a networked client and a server, since there is significant overlap between the two. However, there are a few functions here and there that are meant to be exclusively called by the client or server, and accidentally calling a client function on the server (or vice versa) is a significant source of bugs.
To reduce these sorts of programming errors, I'm trying to tag functions so that they'll raise a ruckus if they're misused. My current solution is a simple macro at the start of each function that calls an assert if the client or server accesses members they shouldn't. However, this runs into problems when there are multiple derived instances of classes, in that I have to tag the implementation as client or server side in EVERY child class.
What I'd like to be able to do is put a tag in the virtual member's signature in the base class, so that I only have to tag it once and not run into errors by forgetting to do it repeatedly. I've considered putting a check in a base class implementation and then referring to it with something like base::functionName, but that runs into the same issue as far as needing to manually add the function call to every implementation. Ideally, I'd be able to have parent versions of the function called automatically like default constructors do.
Does anybody know how to achieve something like this in C++? Is there an alternate approach I should be considering?
Thanks!
Another approach might be to override a different method than the one your callers actually call:
class Base {
public:
void doit(const Something &);
protected:
virtual void real_doit(const Something &);
};
class Derived: public Base {
protected:
virtual void real_doit(const Something &);
};
The implementation of Base::doit() could do the check to make sure that it's being called in the right environment, and then call the virtual real_doit() function. Derived classes would override the protected virtual function, and users of either class wouldn't be able to call the protected function.
The Base::doit() function is not virtual so that derived classes can't accidentally override the wrong one. (People can try, but hopefully they'll notice soon enough when it's not called.)
What you've proposed is incredibly complex. It sounds like a simpler solution would be
class CommonStuff {
// all common code that anybody can safely call
};
class ServerBase : public CommonStuff {
// only what the server is allowed to call; can safely be overwritten
};
class ClientBase : public CommonStuff {
// only what the client is allowed to call; can safely be overwritten
};
Compile-time enforcements are much better than any sort of runtime enforcement.
There's not a way within the language (that I know of) to do what you're asking without redesigning your classes. The simplest solution may be to have a Client interface (pure virtual) class that does not declare server functions, and a Server interface class that doesn't declare client functions, and have your consolidated code inherit (publicly) from both interfaces. Then in your client program, use a reference (or pointer) to the Client interface, which does not allow access to any methods not declared in the Client interface. On the server, use the Server interface.
This will also allow you to use derived classes as Server or Client as well.
I would consider splitting this library into three libraries: A base library that has most everything, a server-only library, and a client-only library. As long as the client doesn't use the server library, you're good. You may end up adding a few extra classes (class Processor might split into BaseProcessor, ClientProcessor, and ServerProcessor, where each subclass has one additional function that the base doesn't.)
If that won't work, could you put the server/client check in the class constructor, and call the assertion there? (That would only work if the server-only or client-only is granular to the class, not to the method.)
If that won't work, would it make any sense to actually compile different versions of your library, based on whether it's a server or client build? Surround the methods, and their declarations, with #ifdef SERVERBUILD and #ifdef CLIENTBUILD, and include some checks to make sure they aren't both defined (#if defined(SERVERBUILD) && defined(CLIENTBUILD), #error Can't define both!).
I voted up Greg Hewgill's answer, but it got me thinking about ways to add "aspects" such as you request. I used his naming convention here (class Base and method doit):
class Base {
protected:
class Aspect {
public:
Aspect(int x) {
std::cout << "aspect" << std::endl;
}
};
public:
virtual void doit(const Something &arg, const Aspect hook = 0)
{
std::cout << "doit(" << arg << ")" << std::endl;
}
};
Callers can just say base.doit(arg) since Aspect is a default argument. Its constructor runs before doit and its destructor (not pictured) runs after. Sadly my first idea to make the default argument hook = this is not allowed.
Children can override doit with the same signature and get the same effect.
My gui application supports polymorphic timed events so that means that the user calls new, and the gui calls delete. This can create a problem if the runtimes are incompatible.
So I was told a proposed solution would be this:
class base;
class Deallocator {
void operator()(base* ptr)
{
delete ptr;
}
}
class base {
public:
base(Deallocator dealloc)
{
m_deleteFunc = dealloc;
}
~base()
{
m_deleteFunc(this);
}
private:
Deallocator m_deleteFunc;
}
int main
{
Deallocator deletefunc;
base baseObj(deletefunc);
}
While this is a good solution, it does demand that the user create a Deallocator object which I do not want. I was however wondering if I provided a Deallocator to each derived class: eg
class derived : public base
{
Deallocator dealloc;
public:
Derived() : base(dealloc);
{
}
};
I think this still does not work though. The constraint is that:
The addTimedEvent() function is part of the Widget class which is also in the dll, but it is instanced by the user. The other constraint is that some classes which derive from Widget call this function with their own timed event classes.
Given that "he who called new must call delete" what could work given these constraints?
Thanks
I suggest that you study the COM reference-counting paradigm (AddRef and Release). This allows more flexible lifetime and guarantees that the correct deallocator is used, because the object deletes itself.
Please note that if you're sharing class objects across DLL boundaries, you could have much bigger problems that just using the same allocator. There's the whole one-definition-rule to account for, and calling conventions, data layout, and name mangling schemes that differ between compilers. So if you want a reusable library, you really need to adopt the COM way of doing things with reference counting, self-deletion, and an interface containing only pure virtual functions. Whether you build real COM objects or your own COM-like system would depend on your other requirements.
The first thing that comes to mind is to give the base class a virtual (abstract?) SelfDestruct method. Assuming that the consumer of your DLL passes a class he derived himself, he will know how to deallocate it.
If he can pass classes which you have written, then you've got more problems. I suggest disallowing allocating such classes and providing a static method for allocating them with your own allocator.
I'm not sure if I've explained my idea very clearly... if not, please ask, I'll provide code later.
What could work with the given constraints is that you associate a deleter function-pointer with each TimedEvent, where both are specified as arguments to addTimedEvent.
To relieve the burden of the client to create a custom deleter function, you can provide an inline deleter function as a member of the anonymous namespace in the header of your widget class.
For example:
// Widget header
class base;
namespace {
inline void default_deleter(base* p)
{
delete p;
}
}
class Widget
{
public:
addTimedEvent(base* event, void(*deleter)(base*));
};
The advantage of the inline function is that it will be compiled in the context of the client code, so delete will also use a compatible deallocator as the client used to allocate the event.
Edit: Made the deleter function a member of the anonymous namespace. This is needed to avoid ODR violations.
Without the namespace, you get two functions default_deleter that have the same external name (so they are the same as far as the linker is concerned), but with different semantics, because they refer to different deallocators.
With the anonymous namespace, all instances of default_deleter become separate entities for the linker. This has the (unfortunate) side-effect that you can no longer use the function as a default argument to addTimedEvent.