C++ class extension technology - c++

I know the official answer for "extension class in C++ like objective-C or c#" is NO. But is there any hack ways to implement this? And what is the cost?
I ask this because my colleague use my parser to generate C++ class files from a special format txt file. They complained that it is difficult to extension the class.
I can't force them to use inheritance, because the class generated is like this:
class A {}
class B : A {}
if my colleague extends A like this:
class C : A {}
then the B class will not benefit from the C class. That means: In our situation, if class C : A, B is meant to inherit from A, then now B should inherit from C now. But it is not possible since the B has hard code to inherit from A. That means, inheritance is not a good option, the truly demand is to extend A.
And using A as a member in a new class is not an option, either. Since our logic is more like a "is-A", not a "has-A", force make A as a member will make the code hard to read.
Currently they directly modify the class header file, and any new member functions is implement in a new cpp file(thanks to C++ class file structure), so if the class changes, the origin cpp file will regenered, they won't care about it, while they use git to merge the new generated header file to the file they have modified.
I can write a parser to scan the header file and do the merge, but write a parser to fully implement C++ standard BNF(http://www.externsoft.ch/download/cpp-iso.html) is difficult.
Currently I decide to use macros, like the mechanism used by flex and bison to replace the action in .y file to the generated c file. But I wondered if there's a easy way.

A common C++ solution is freeFunction(A&) instead of creating class B. Unlike pure OO languages, C++ has free functions which are not class members. Your freeFunction_B(A&) and your colleague's freeFunction_C(A&)` will not interfere.
Obviously this is not a solution when you need to add data members. In that case, there's another option. Leave open the base class:
template<typename BASE> class B : public BASE {
// ...
}
This allows both B<A> and B<C<A>>. Slight downside: C<B<A>> is not the same type as B<C<A>>, which is logical. The members have to be in a certain order in memory, and there are two choices.
(General advice: code generation and C++? That means templates)

As doing a research for some times, I think the term "monkey patch" is the technology what I'm looking for, but it seems only can be implemented with languages which has the reflection feature.
Currently I use "has-a" extension in my code instead of "is-a" to avoid changing the generated code.

Related

Is forward declaring a class a correct way to hide the implementation? [duplicate]

This question already has answers here:
Is the PIMPL idiom really used in practice?
(12 answers)
Closed 8 years ago.
Backgrounder:
The PIMPL Idiom (Pointer to IMPLementation) is a technique for implementation hiding in which a public class wraps a structure or class that cannot be seen outside the library the public class is part of.
This hides internal implementation details and data from the user of the library.
When implementing this idiom why would you place the public methods on the pimpl class and not the public class since the public classes method implementations would be compiled into the library and the user only has the header file?
To illustrate, this code puts the Purr() implementation on the impl class and wraps it as well.
Why not implement Purr directly on the public class?
// header file:
class Cat {
private:
class CatImpl; // Not defined here
CatImpl *cat_; // Handle
public:
Cat(); // Constructor
~Cat(); // Destructor
// Other operations...
Purr();
};
// CPP file:
#include "cat.h"
class Cat::CatImpl {
Purr();
... // The actual implementation can be anything
};
Cat::Cat() {
cat_ = new CatImpl;
}
Cat::~Cat() {
delete cat_;
}
Cat::Purr(){ cat_->Purr(); }
CatImpl::Purr(){
printf("purrrrrr");
}
I think most people refer to this as the Handle Body idiom. See James Coplien's book Advanced C++ Programming Styles and Idioms. It's also known as the Cheshire Cat because of Lewis Caroll's character that fades away until only the grin remains.
The example code should be distributed across two sets of source files. Then only Cat.h is the file that is shipped with the product.
CatImpl.h is included by Cat.cpp and CatImpl.cpp contains the implementation for CatImpl::Purr(). This won't be visible to the public using your product.
Basically the idea is to hide as much as possible of the implementation from prying eyes.
This is most useful where you have a commercial product that is shipped as a series of libraries that are accessed via an API that the customer's code is compiled against and linked to.
We did this with the rewrite of IONA's Orbix 3.3 product in 2000.
As mentioned by others, using his technique completely decouples the implementation from the interface of the object. Then you won't have to recompile everything that uses Cat if you just want to change the implementation of Purr().
This technique is used in a methodology called design by contract.
Because you want Purr() to be able to use private members of CatImpl. Cat::Purr() would not be allowed such an access without a friend declaration.
Because you then don't mix responsibilities: one class implements, one class forwards.
For what is worth, it separates the implementation from the interface. This is usually not very important in small size projects. But, in large projects and libraries, it can be used to reduce the build times significantly.
Consider that the implementation of Cat may include many headers, may involve template meta-programming which takes time to compile on its own. Why should a user, who just wants to use the Cat have to include all that? Hence, all the necessary files are hidden using the pimpl idiom (hence the forward declaration of CatImpl), and using the interface does not force the user to include them.
I'm developing a library for nonlinear optimization (read "lots of nasty math"), which is implemented in templates, so most of the code is in headers. It takes about five minutes to compile (on a decent multi-core CPU), and just parsing the headers in an otherwise empty .cpp takes about a minute. So anyone using the library has to wait a couple of minutes every time they compile their code, which makes the development quite tedious. However, by hiding the implementation and the headers, one just includes a simple interface file, which compiles instantly.
It does not necessarily have anything to do with protecting the implementation from being copied by other companies - which wouldn't probably happen anyway, unless the inner workings of your algorithm can be guessed from the definitions of the member variables (if so, it is probably not very complicated and not worth protecting in the first place).
If your class uses the PIMPL idiom, you can avoid changing the header file on the public class.
This allows you to add/remove methods to the PIMPL class, without modifying the external class's header file. You can also add/remove #includes to the PIMPL too.
When you change the external class's header file, you have to recompile everything that #includes it (and if any of those are header files, you have to recompile everything that #includes them, and so on).
Typically, the only reference to a PIMPL class in the header for the owner class (Cat in this case) would be a forward declaration, as you have done here, because that can greatly reduce the dependencies.
For example, if your PIMPL class has ComplicatedClass as a member (and not just a pointer or reference to it) then you would need to have ComplicatedClass fully defined before its use. In practice, this means including file "ComplicatedClass.h" (which will also indirectly include anything ComplicatedClass depends on). This can lead to a single header fill pulling in lots and lots of stuff, which is bad for managing your dependencies (and your compile times).
When you use the PIMPL idiom, you only need to #include the stuff used in the public interface of your owner type (which would be Cat here). Which makes things better for people using your library, and means you don't need to worry about people depending on some internal part of your library - either by mistake, or because they want to do something you don't allow, so they #define private public before including your files.
If it's a simple class, there's usually isn't any reason to use a PIMPL, but for times when the types are quite big, it can be a big help (especially in avoiding long build times).
Well, I wouldn't use it. I have a better alternative:
File foo.h
class Foo {
public:
virtual ~Foo() { }
virtual void someMethod() = 0;
// This "replaces" the constructor
static Foo *create();
}
File foo.cpp
namespace {
class FooImpl: virtual public Foo {
public:
void someMethod() {
//....
}
};
}
Foo *Foo::create() {
return new FooImpl;
}
Does this pattern have a name?
As someone who is also a Python and Java programmer, I like this a lot more than the PIMPL idiom.
Placing the call to the impl->Purr inside the .cpp file means that in the future you could do something completely different without having to change the header file.
Maybe next year they discover a helper method they could have called instead and so they can change the code to call that directly and not use impl->Purr at all. (Yes, they could achieve the same thing by updating the actual impl::Purr method as well, but in that case you are stuck with an extra function call that achieves nothing but calling the next function in turn.)
It also means the header only has definitions and does not have any implementation which makes for a cleaner separation, which is the whole point of the idiom.
We use the PIMPL idiom in order to emulate aspect-oriented programming where pre, post and error aspects are called before and after the execution of a member function.
struct Omg{
void purr(){ cout<< "purr\n"; }
};
struct Lol{
Omg* omg;
/*...*/
void purr(){ try{ pre(); omg-> purr(); post(); }catch(...){ error(); } }
};
We also use a pointer-to-base class to share different aspects between many classes.
The drawback of this approach is that the library user has to take into account all the aspects that are going to be executed, but only sees his/her class. It requires browsing the documentation for any side effects.
I just implemented my first PIMPL class over the last couple of days. I used it to eliminate problems I was having, including file *winsock2.*h in Borland Builder. It seemed to be screwing up struct alignment and since I had socket things in the class private data, those problems were spreading to any .cpp file that included the header.
By using PIMPL, winsock2.h was included in only one .cpp file where I could put a lid on the problem and not worry that it would come back to bite me.
To answer the original question, the advantage I found in forwarding the calls to the PIMPL class was that the PIMPL class is the same as what your original class would have been before you pimpl'd it, plus your implementations aren't spread over two classes in some weird fashion. It's much clearer to implement the public members to simply forward to the PIMPL class.
Like Mr Nodet said, one class, one responsibility.
I don't know if this is a difference worth mentioning but...
Would it be possible to have the implementation in its own namespace and have a public wrapper / library namespace for the code the user sees:
catlib::Cat::Purr(){ cat_->Purr(); }
cat::Cat::Purr(){
printf("purrrrrr");
}
This way all library code can make use of the cat namespace and as the need to expose a class to the user arises a wrapper could be created in the catlib namespace.
I find it telling that, in spite of how well-known the PIMPL idiom is, I don't see it crop up very often in real life (e.g., in open source projects).
I often wonder if the "benefits" are overblown; yes, you can make some of your implementation details even more hidden, and yes, you can change your implementation without changing the header, but it's not obvious that these are big advantages in reality.
That is to say, it's not clear that there's any need for your implementation to be that well hidden, and perhaps it's quite rare that people really do change only the implementation; as soon as you need to add new methods, say, you need to change the header anyway.

How to use c++ classes without names?

I encountered a problem in opensource c++ code. The following is a small and simplified version to describe my problem:
#include <iostream>
using namespace std;
#define TOGETHER2(a,b) a ## b
#define TOGETHER(a,b) TOGETHER2(a,b)
#define GENERATE_NAME(a) TOGETHER(a,__COUNTER__)
#define GENERATE GENERATE_NAME(__seed_)
class base{
}b;
class GENERATE:public base{
}GENERATE;
class GENERATE:public base{
}GENERATE;
class GENERATE:public base{
}GENERATE;
class GENERATE:public base{
}GENERATE;
int main(){
return 0;
}
As we can see, the author defines several classes, which inherites a base class. But the author do not care about the names of the classes. So I wonder how can I use those classes without specifying their names?
Is this a kind of design pattern in c++ that I don't know?
Thank you :)
I want to add my guesses to make the question clear.
My guesses:
The names of these classes are generated from __seed_, but when I search through the files, I can not find other references to __seed_, So I am sure The author did not use the names __seed_1, __seed_2 to create classes. (Actually the author said the the comments that she did not care about the names of the classes)
I also guessed that the author may have used those classes through the interface defined in the base class(virtual function). To do that, the author still needed to create these classes, but as I mentioned I could not find __seed_ in other parts of the code, So the author couldn't create classes, and therefore virtual function do not work either.
Actually, I tried remove these class definitions, and strangely the code compiles correctly. However, It lost some of functionalities, but It did not just core dump. It could still finish some tasks successfully u
So, do anyone know:
How can we use those classes without specifying their names?
Is this design a certain kind of design pattern?
In which situation should we define class without caring about their names?
As I mentioned, I removed some part of the code, and It compiled. How could this happen? I mean, Since I remove many classes from the source code, then If other parts of the code references those classes, the source can not compile. And If it compiles, Can I just conclude that those classes are not needed?
ADDED:
As some of you recommended,
the full source code is here: MIT Cryptdb. In the file ./main/rewrite_const.cc, the author used macro ANON(lion 25) to define many classes without caring about their names.
Really appreciate your help :)
I recommend you to edit the code and add names for the classes. This is a strange design pattern, and I wouldn't recommend you to use such pattern for anything, unless you want to prevent others from using your classes.
If the author wants you to use those classes, there is probably some way you can use them without editing the code and adding the names. You should consult the documentation for this.
As I mentioned, I removed some part of the code, and It compiled. How could this happen? I mean, Since I remove many classes from the source code, then If other parts of the code references those classes, the source can not compile. And If it compiles, Can I just conclude that those classes are not needed?
All those generated classes are derived from the base class. So if you remove one class, all classes that come after it receive a new generated name. If the code now compiles, it means the other code is only calling the methods that are part of the base class. But the other code is now using other classes than what it originally used, which causes the errors you observe.
Consider this:
Initially the generated classes have names A, B, and C.
You remove class A.
Now the generated classes have names A and B. Class named C no longer exists, so the code that uses it should no longer compile. And the code that used class A and B before, it is now using the classes that used to be B and C.
These classes do have names. Only that these names are not revealed to the human reader and are not specified before the preprocessor has run. (If you run the compiler with option -E, it will only run the preprocessor stage and output the code as the compiler proper sees it, including the class names.)
AFAIK, there is no sensible reason to hide the names in this way. If the author doesn't want humans to write code that uses these classes, then there are other ways.
Defining such names in a header file to be included by the user implies that they cannot be used from within the library other than via polymorphism (because the library cannot know their names). This is the reason why removing them made no difference regarding compilation.

Objective-C++: Headers and Class Methods

I've been learning Objective-C for the last few months with the goal of writing iOS games. I want to be able to make the games relatively easy to port to other platforms, so I've also been simultaneously learning C++. My plan is to write most of the game in C++ and write the drawing and game loop in Objective-C. I know (at least I've been told) this is possible, but there are a few things that I'm still confused about.
I'm still pretty new to C++, and coming originally from Java, is it a bad idea to have functions return type be void?
Is there a way to write class functions? ie. className.function(); rather than object.function();
I've never needed header files for my C++ files before. Could someone point me in the direction of an example? Preferably one that has a constructor method? I don't know what to make its return type. (It should be a pointer to the class right?)
I'm going to assume your questions are about how to write C++, as that seems to be what you're asking.
Not at all, void functions are well-accepted in nearly all languages, C++ and Objective-C included. (Though many people prefer returning a bool success/fail value)
You're probably looking for static functions. These don't require instantiation, but there are some limits on their use (see here for more info).
Any non-trivial C++ project should use header files. They serve several purposes, including keeping your code more organized and modular, decreasing compile-time in many cases, and aiding in conceptualizing your design before you think about implementation.
An important thing to note when breaking your class into .h and .cpp files is the use of the scope modifier :: when defining functions. When defining the function public void foo() in your .cpp file, after having declared it in your header, you must use public void ClassName::foo() { }. This is because you defined foo while in the class ClassName { } block in your header, but you are now in the global scope.
(As for your question about C++ constructors, if should be public ClassName::ClassName(); and you don't need to return anything).
Now obviously, many of these points differ in Objective-C. For example, the init method (comparable to the C++ constructor) does, as you said, return a pointer to the object being inited. If you want specific information on writing cross-language apps, you should update your question to be more specific, or open a new question.
No that is fine.
Yes: Assume SomeClass.h:
#pragma once
class SomeClass {
public:
static bool myStaticMethod();
};
and in SomeClass.cpp:
#include "SomeClass.h"
bool SomeClass::myStaticMethod() {
// A static method
return true;
}
See the first part of 2, above.
Some other notes:
A. Change all your Objective-C interface code to Objective-C++ by renaming all the .m files to .mm. This way you can use your C++ code freely.
B. I couldn't think of a B.

How to create union class structure?

Say class A had method do(); and class B had field data;. I wonder if there is a way (using Boost for example) to create a class union from A and B which would have method do() and field data?
Union has a specific meaning in c and c++, and it's not what you want. It sounds like you want is multiple inheritance, a class C that inherits from both A and B. Alternatively, you could also have a class C that contains instances of classes A and B. Oftentimes composition ("has-a") is preferable over inheritance ("is-a").
Not a chance in hell. This would require reflection, which does not currently exist in the C++ language, and even if it did, it's highly unlikely that anybody would have implemented such a thing because why would you even want to do that. The closest you can get is if you inherited from both classes.

Could C++ have not obviated the pimpl idiom?

As I understand, the pimpl idiom is exists only because C++ forces you to place all the private class members in the header. If the header were to contain only the public interface, theoretically, any change in class implementation would not have necessitated a recompile for the rest of the program.
What I want to know is why C++ is not designed to allow such a convenience. Why does it demand at all for the private parts of a class to be openly displayed in the header (no pun intended)?
This has to do with the size of the object. The h file is used, among other things, to determine the size of the object. If the private members are not given in it, then you would not know how large an object to new.
You can simulate, however, your desired behavior by the following:
class MyClass
{
public:
// public stuff
private:
#include "MyClassPrivate.h"
};
This does not enforce the behavior, but it gets the private stuff out of the .h file.
On the down side, this adds another file to maintain.
Also, in visual studio, the intellisense does not work for the private members - this could be a plus or a minus.
I think there is a confusion here. The problem is not about headers. Headers don't do anything (they are just ways to include common bits of source text among several source-code files).
The problem, as much as there is one, is that class declarations in C++ have to define everything, public and private, that an instance needs to have in order to work. (The same is true of Java, but the way reference to externally-compiled classes works makes the use of anything like shared headers unnecessary.)
It is in the nature of common Object-Oriented Technologies (not just the C++ one) that someone needs to know the concrete class that is used and how to use its constructor to deliver an implementation, even if you are using only the public parts. The device in (3, below) hides it. The practice in (1, below) separates the concerns, whether you do (3) or not.
Use abstract classes that define only the public parts, mainly methods, and let the implementation class inherit from that abstract class. So, using the usual convention for headers, there is an abstract.hpp that is shared around. There is also an implementation.hpp that declares the inherited class and that is only passed around to the modules that implement methods of the implementation. The implementation.hpp file will #include "abstract.hpp" for use in the class declaration it makes, so that there is a single maintenance point for the declaration of the abstracted interface.
Now, if you want to enforce hiding of the implementation class declaration, you need to have some way of requesting construction of a concrete instance without possessing the specific, complete class declaration: you can't use new and you can't use local instances. (You can delete though.) Introduction of helper functions (including methods on other classes that deliver references to class instances) is the substitute.
Along with or as part of the header file that is used as the shared definition for the abstract class/interface, include function signatures for external helper functions. These function should be implemented in modules that are part of the specific class implementations (so they see the full class declaration and can exercise the constructor). The signature of the helper function is probably much like that of the constructor, but it returns an instance reference as a result (This constructor proxy can return a NULL pointer and it can even throw exceptions if you like that sort of thing). The helper function constructs a particular implementation instance and returns it cast as a reference to an instance of the abstract class.
Mission accomplished.
Oh, and recompilation and relinking should work the way you want, avoiding recompilation of calling modules when only the implementation changes (since the calling module no longer does any storage allocations for the implementations).
You're all ignoring the point of the question -
Why must the developer type out the PIMPL code?
For me, the best answer I can come up with is that we don't have a good way to express C++ code that allows you to operate on it. For instance, compile-time (or pre-processor, or whatever) reflection or a code DOM.
C++ badly needs one or both of these to be available to a developer to do meta-programming.
Then you could write something like this in your public MyClass.h:
#pragma pimpl(MyClass_private.hpp)
And then write your own, really quite trivial wrapper generator.
Someone will have a much more verbose answer than I, but the quick response is two-fold: the compiler needs to know all the members of a struct to determine the storage space requirements, and the compiler needs to know the ordering of those members to generate offsets in a deterministic way.
The language is already fairly complicated; I think a mechanism to split the definitions of structured data across the code would be a bit of a calamity.
Typically, I've always seen policy classes used to define implementation behavior in a Pimpl-manner. I think there are some added benefits of using a policy pattern -- easier to interchange implementations, can easily combine multiple partial implementations into a single unit which allow you to break up the implementation code into functional, reusable units, etc.
May be because the size of the class is required when passing its instance by values, aggregating it in other classes, etc ?
If C++ did not support value semantics, it would have been fine, but it does.
Yes, but...
You need to read Stroustrup's "Design and Evolution of C++" book. It would have inhibited the uptake of C++.