In the threading module, names like RLock, Semaphore and Event are all factory functions, while the name of implementation classes are prefixed by underscores.
The factory functions just pass all arguments they received to the underlying constructors.
So what's the benefit of doing this?
The thread-sig archives seem to have disappeared from the Internet (*), but I'm pretty sure it's prevent you from subclassing things that aren't designed to be subclassed (you really don't want to break synchronization primitives by accident), and the module is old enough that you couldn't do that with new-style class trickery when it was added.
Also note that e.g. RLock has multiple implementation classes.
*) Well, I found some remnants on an FTP server in Greece, but that didn't have the original spec.
There is no real advantage.
Guido added the module 1998; the first revision already includes those factory functions. Perhaps he had plans for those factory functions, perhaps he was looking at the Java implementation and copied over some idioms, perhaps he wanted to make things pluggable with a C re-implementation in the back of his head.
We can only guess, or ask Guido directly.
Related
I'm new to C++, and I have this question because I try to compare C++ to Java.
In Java, interface tell the developer which function to implement in order to use the Class or function I provide. For example, by specify the param type as Runnable, I tell the developer that the param I accepted need to have a run method, Iterable tells that the object need to have an iterator.
In C++, so far as I learned, I have encounter many cases that in compiling time, the compiler ask for some operator. And sometimes I even don't know how to specify the requirement of the param that others pass in.
To summarize my question, what's the general idea of approach when designing an template that I hope can handle more generic usage?
I know C++ is not an 100% object-orient language, so I'm still trying to get used to it, when shifting from Java.
AFAIK Java interfaces are for runtime polymorphism; in C++ they are plain classes that contain only pure virtual methods. Java needs a separate language entity for them as it supports only single inheritance for classes (which simplifies many corner cases) but allows multiple inheritance of interfaces; as C++ allows full multiple inheritance for classes in general, there's no need for this distinction.
OTOH, in C++ you don't use interfaces nearly as often - especially in the standard library, especially in the container part. Often compile-time polymorphism is used, in the form of templates.
Unfortunately as of today there's no way to express what operations should a type parameter of a template provide; the template-equivalent of interfaces - "concepts" - is being worked on by the C++ standard committee - unfortunately since many years now - and it's not ready yet.
For now you may only spell out your requirements in the documentation. If a type passed to the template doesn't satisfy them, you'll just get a compilation error pointing to the template code that tries to do something the type doesn't support. This leads to quite some confusion and horrible error messages, so you can try to mitigate this by strategically placing static_assert about the provided type checking if it conforms to what you need, thus providing better diagnostics in case of error.
I'm designing (brainstorming) a C++ plugin framework for an extensible architecture.
Each plugin registers an interface, which is implemented by the plugin itself.
Such framework may be running on relatively capable embedded devices (e.g. Atom/ARM) so I can use STL and Boost.
At the moment I've managed to write a similar framework, in which interfaces are known in advance and plugins (loaded from dynamic libraries) register the objects implementing them. Those objects are instantiated as needed by their factory methods, and methods are called correctly.
Now I want to make it more flexible, having plugins register new interfaces (not just implementing the existing ones) thus extending the API available to the framework users.
I thought of using a std::map<std::string, FunctionPtr>, which is also mentioned by several articles and stackoverflow replies I've read. Unfortunately it doesn't seem to capture the case of different method interfaces.
I feel it might have something to do with template metaprogramming, or traits perhaps, but I can't figure out how it should work exactly. Can anyone help?
Try looking at XPCOM which solves these problems for you - by sortof re-implementing COM.
You have the issue of not knowing what interface the plugin provides to your application, so you need a way for the developer to access it, without the compiler knowing what it is (though, if you supply a header file, then suddenly you do know what it is and you can compile it without any need for plugin unknown-interface fanciness)
so, you're going to have to rely on runtime determinism of the interface, that roughly requires you to define the interface in some way so that the framework can call arbitrary methods on it, and I think the only realistic way you can do that is to define each interface as a set of function pointers that are loaded individually and then stored in data for the user to call. And that pretty much means a map of function pointers to names. It also means you can only user compiler niceties (such as overloading) by making the function names unique. The compiler does this for you by 'mangling' all functions to unique, coded names.
Type Traits will help you wrap your imported functions in your framework, so you can inspect them and create classes that work with any imported type, but it isn't going to solve the main problem of importing arbitrary functions.
Possibly one approach that you'll want to read is Metaclasses and Reflection by Vollmann. This was referenced by the C++ standard body, though I don't know if it will become part of a future spec. Alternatively you can look at Boost.Extension
Maybe the first thing you need check is COM.
Anything that can be done with templates, can be done without, though perhaps in a much less convenient way, by writing "template instances" by hand.
If your framework was compiled without seeing a declaration of class MyNewShinyInterface, it cannot store pointers of type MyNewShinyInterface *, and cannot return them to the framework users. No amount of template wizardry can change that. The framework can only store an pass around pointers to some base class. The users will have to do a dynamic_cast to retrieve the correctly typed pointer.
The same is true about function pointers, only functions have no base classes and one will have to do the error-prone reinterpret_cast to retrieve the right type. (This is just another reason to prefer proper objects over function pointers.)
I don't really understand how ObjC can efficiently rely on messages. Does this mean a kernel such as mach has to be designed with this idea ?
Objective C seems like a good language, but I can't find it easier to grasp than C++.
How is a message system built in a language an advantage ?
The messaging in the Objective-C is not directly related to the messaging in the mach kernel. It's implemented as a highly-tuned function called objc_msgSend. The call
[obj messageWithX:x andY:y];
is translated to the C call
objc_msgSend(obj,#selector(messageWithX:andY:),x,y);
objc_msgSend is written directly in assembly language to be maximally optimized. It resolves the method call dynamically in a very efficient way. This blog post would be a good place to start understanding how it is implemented.
Whether it's easier or harder to grasp than C++ will depend on your background and your taste. The flavors of object-orientedness supported by C++ and Objective-C are quite different, and so it's difficult to compare.
Objective-C's messaging system is highly dynamic, and most of the decision can be done at the run time. C++'s member function invocation system is more static, and tries to do as much as possible at the compile time.
One merit of the dynamical nature of Objective-C is that you can change the class system at run time, but that's not necessarily related to the messaging nature. For example, the messaging system in mach doesn't do that, as far as I understand.
One feature directly related to the messaging nature is that an object can capture a message which it does not understand, and then forward it to other objects. This can be done in mach: the receiver of a message can either be in the kernel space, in the user space, or even in another machine, and the sender of the message doesn't need to care about it. This adds more flexibility in designing the kernel. (But this feature is not used in the mach kernel in OS X.)
Objective-C messaging is not built into the kernel, it is build into the Objective-C run-time.
Most of the magic is done in a function called objc_msgSend(). If you write a Objective-C code like this:
[myObject doStuffWith:something];
The compiler will actually generate the same code as if you had typed this:
objc_msgSend(myObject, #selector(doStuffWith:), something);
The implementation of of objc_msgSend() is quite fast and smart. Fast by caching frequently used selector, and smart in that it allows for implementation resolution as late as possible. What objc_msgSend() in practice do is a hash lookup for the selector to find an actual implementation.
One advantage that you have here is that if an implementation for a method is not found, then the object can at run-time either:
Defer the call to another object in order to act as a proxy.
Dynamically act on the selector.
Dynamically bind an implementation to the previously unknown selector.
The most obvios advantage of a dynamically typed language with messages is what you see in delegates. As you might have noticed in for example the UITableViewDelegate protocol; not all methods are declared as required.
This allows clients conforming to (implementing) a protocol to infer the default behavior simply by not implementing the delegate method at all. Whereas in for example Java it is quite common to apart from an interface Foo also have an abstract default implementation FooAdapter that implements default implementations for each and every method in the interface.
I need to develop a C++ front-end GUI using MSVC that needs to communicate with the bank-end library that is compiled with C++ Builder.
How can we define our interfaces so that we don't run into CRT library problems?
For example, I believe we will be unable to safely pass STL containers back and forth. Is that true?
I know I can pass POD types safely, but I am hoping that I can use some more sophisticated data structures as well.
You might find this article interesting Binary-compatible C++ Interfaces. The lesson in general is, never pass STL container, boost or anything of the like. Like the two other answers your best bet is to stick with PODs and functions with a calling convention specified.
Since implementations of the STL vary from compiler to compiler, it is not safe to pass STL classes. You can then either require the user to a specific implementation of the STL (and probably a specific version as well), or simply not use the STL between libraries.
Further more stick with the calling conventions where the behaviour can be considered cross compiler frieindly. For instance __cdecl and __stdcall will be handled equally on most compilers, while the __fastcall calling convention will be a problem, especially if you wish to use the code in C++ Builder.
As the article "Binary-compatible C++ Interface" mentions you can use interface as well, as long as you remember a few basic principles.
Always make interfaces pure virtual classes (that is no implementations).
Make sure to use a proper calling convention for the member functions in the interface (the article mentions __stdcall for Windows.
Keep the memory clean up at the same side of the DLL boundary.
And quite a few other things, like don't use exceptions, don't overload functions in the interface (compilers treat this differently), etc. Find them all at the bottom of the article.
You might want to read more about the Component Object Model (COM) if you choose to go with the C++ interfaces, to get an idea about how and why this will be able to work across compilers.
You should be able to pass data that you can safely pass via a C interface, in other words, PODs. Everything over and above PODs that is being passed by regular C or C++ function calls will run into issues with differing object layouts and different implementations of the runtime libraries.
You probably will be able to pass structs of PODs if you are very careful about how you lay them out in memory and ensure that both compilers are using the same data packing etc. Over and above C structs, you pretty much have a creek/paddle problem.
For passing more sophisticated data types, I would look into object component technologies like COM, CORBA or other technologies that allow you to make remote or cross-process function calls. These would solve the problem of marshalling the data between compilers and processes and thus solve your 'pod-only' problem.
Or you could write the front end using C++-Builder and save yourself a lot of grief and headaches.
I ran into problems when passing STL-Containers even when using the same STL-Implementation, but having set different levels of debug information etc. Therefore Passing PODs will be OK. C++ Containers will almost certainly result in problems.
The MFC has all class names that start with C. For example, CFile and CGdiObject. Has anyone seen it used elsewhere? Is there an official naming convention guide from Microsoft that recommends this style? Did the idea originate with MFC or was it some other project?
It's evil. Don't use Hungarian Notation for anything but abstracted things.
For instance, btnSubmit is ok to describe a button named Submit(which would have an accompanying lblSubmit for the label next to the button)
But things like CMyClass for Class and uiCount for unsigned integer named count does not help programmers and just leads to extra wasteful typing.
Something a bit similar is used in Symbian C++, where the convention is that:
T classes are "values", for example TChar, TInt32, TDes
R classes are handles to kernel (or other) resources, for example RFile, RSocket
M classes are mixins, which includes interfaces (construed as mixins with no function implementations). The guideline is that multiple inheritance should involve at most 1 non-M class.
C classes are pretty much everything else, and derive from CBase, which has some stuff in it to help with resource-handling.
HBufC exists primarily to generate confused posts on Symbian forums, and having its very own prefix is just the start. The H stands for "huh?", or possibly "Haw, haw! You have no STL!" ;-)
This is close in spirit to Apps Hungarian Notation rather than Systems Hungarian notation. The prefix tells you something about the class which you could look up in the documentation, but which you would not know otherwise. The whole point of naming anything in programming is to provide such hints and reminders, otherwise you'd just call your classes "Class001", "Class002", etc.
Systems Hungarian just tells you the type of a variable, which IMO is nothing to get very excited about, especially in a language like C++ where types tend to be either repeated constantly or else completely hidden by template parameters. Its analogue when naming types is the Java practice of naming all interfaces with I. Again, I don't get very excited about this (and neither do the standard Java libraries), but if you're going to define an interface for every class, in addition to the interfaces which are actually used for polymorphism in non-test situations, then you need some way to distinguish the two.
That was a old C++ coding style, and MFC was probably one of the last things to use it.
It was usually just a convention of C++ (and maybe a few other languages), and hence it started falling out of favor as the languages became more interoperable, through COM and then .NET.
You still see it's cousin, the "I" prefix for interfaces, pretty often. I've always found it interesting that "I" survived when "C" died, but that was probably because interfaces were used so heavily in COM interoperability.
I remember Borland compilers were comming with libraries where class names started with 'T'. Probably for "type" :)
I can't answer all your questions, but as far as I know, it's just to distinguish the MFC classes from other classes -- a form of Hungarian Notation.
Interestingly, it's apparently controversial not just outside MS, but inside as well.
Years ago naming convention is crucial to help identifying the class, type of even the grouping of the class. Dont forget back then there was no namespace and no/limited intellisense available. C is a form of Hungarian notation but certainly made popular by MFC. Borland and Delphi was using T - as prefix for Type
While MFC and lots of software written for Windows used the "C" convention for classes, you generally don't find the latter in software written for UNIX platforms. I think it was a habit very strongly encouraged by Visual C++. I remember that Visual C++ 6.0 would prefix a "C" to any classes that one created with the class wizard.
See here : http://www.jelovic.com/articles/stupid_naming.htm for a long article on this issue.
Such conventions for variables are useful for languages like Fortran where you don't need to declare the types of your variables before using them. I seem to recall that variables who's names started with "i" or "j" defaulted to integers, and variables who's names started with "r" and other letters defaulted to real (float) values.
That people use similar for languages where you do need to declare variables - or for class definitions - is probably just a relic of someone misunderstanding the old code conventions from languages like Fortran where it actually mattered.
When writing applications that use the Qt libraries, we use a naming convention that distinguishes classes that are directly or indirectly derived from QObject from classes that aren't. This is useful because you can tell from the class name whether or not it supports signals/slots, properties, and all the other goodies that come from QObject.
we use it at work, like many other naming conventions
by many I meant C for classes, p for pointer, m_ for members, s_ for static members, n for integer ... not many documents
personally I find that hungarian notation helps me, in that I can look at a screen full of variables and instantly know what they are as I try and absorb the logic. Your only argument against it I see is "extra typing"