Suppose, there are 2 classes, Foo and ImitateFoo.
ImitateFoo implements an implicit cast operator to act like Foo.
class Foo
{
public:
int DoFoo() { return 1; }
};
class ImitateFoo
{
private:
Foo f;
public:
operator Foo&() { return f; }
};
I want to act on ImitateFoo, like I do on Foo. Especially calling its methods.
ImitateFoo imitator;
Foo& f = imitator; // implicit cast works
f.DoFoo();
static_cast<Foo&>(imitator).DoFoo(); // static cast works as well
imitator.DoFoo(); // does NOT compile -- desired behaviour!
Unfortunately, the last approach does not compile (at least with VS 10.0).
It's for some reasons not possible to overload the .-operator.
Any suggestions how I can achieve the desired behaviour? Is it somehow possible to increase the binding-priority of the cast-operator against the .-operator?
Edit: Why I cannot use Inheritance as the most obvious solution
I have to re-implement a bunch of framework classes. Foo resembles one of them and it's used as a global object throughout the legacy code (which I must not change).
Since I am now in need for unit tests, I need to control the state of these global objects. This is done quite similarly to the way the
PIMPL idiom proposes.
In that case the ImitateFoo class has only one state: it's implementation which is injected and might be changed during runtime. All method calls are redirected to this Foo instance. So actually I could implement the example above as easy as just make a DoFoo non-virtual function in ImitateFoo with redirects to its currents implementation method. Which is in fact what I am doing now.
This works pretty well both for methods and also for operators. But it results in A LOT of bloat code, which does nothing than redirecting.
Contrary to redirecting each method and operator-call by it's own, I wanted to take a step back and look if it's possible to just make the ImitateFoo behave like it's underlaying implementation.
In dynamic languages like Python you could delegate all non explicitely defined methods to another object (here field f). But AFAIK it is not possible in C++.
If inheritance is not an acceptable solution you can explicitely delegate all methods you want ImitateFoo do process, in a kind of duck typing instead of inheritance :
class ImitateFoo
{
private:
Foo f;
public:
operator Foo&() { return f; }
int DoFoo() { return f.DoFoo(); } // explicit delegation
};
It is not as automatic as you could want, but at least :
imitator.DoFoo();
will correctly compile and run.
Seems a bit like a X Y problem, and your proposed solution, although elegant in concept, I don't believe it's possible in C++.
Running in a problem somewhat similar to yours I've used macros to hide the repetitive code, which in your case would be the casting(considering that the actual problem you want is to avoid is to re-write every function/operator , main goal being reducing the amount of code to be written) .
Here's a code snippet
#define CAST(x) (static_cast<Foo&>(x))
...
ImitateFoo f;
CAST(f).DoFoo();
Related
I am wrapping a library which I did not write to make it more user friendly. There are a huge number of functions which are very basic so it's not ideal to have to wrap all of these when all that is really required is type conversion of the results.
A contrived example:
Say the library has a class QueryService, it has among others this method:
WeirdInt getId() const;
I'd like a standard int in my interface however, I can get an int out of WeirdInt no problem as I know how to do this. In this case lets say that WeirdInt has:
int getValue() const;
This is a very simple example, often the type conversion is more complicated and not always just a call to getValue().
There are literally hundreds of function calls that return types likes these and more are added all the time, so I'd like to try and reduce the burden on myself having to constantly add a bajillion methods every time the library does just to turn WeirdType into type.
I want to end up with a QueryServiceWrapper which has all the same functionality as QueryService, but where I've converted the types. Am I going to have to write an identically names method to wrap every method in QueryService? Or is there some magic I'm missing? There is a bit more to it as well, but not relevant to this question.
Thanks
The first approach I'd think is by trying with templates such that
you provide a standard implementation for all the wrapper types which have a trivial getValue() method
you specialize the template for all the others
Something like:
class WeirdInt
{
int v;
public:
WeirdInt(int v) : v(v) { }
int getValue() { return v; }
};
class ComplexInt
{
int v;
public:
ComplexInt(int v) : v(v) { }
int getValue() { return v; }
};
template<typename A, typename B>
A wrap(B type)
{
return type.getValue();
}
template<>
int wrap(ComplexInt type)
{
int v = type.getValue();
return v*2;
};
int x = wrap<int, WeirdInt>(WeirdInt(5));
int y = wrap<int, ComplexInt>(ComplexInt(10));
If the wrapper methods for QueryService have a simple pattern, you could also think of generating QueryServiceWrapper with some perl or python script, using some heuristics. Then you need to define some input parameters at most.
Even defining some macros would help in writing this wrapper class.
Briefly, If your aim is to encapsulate the functionality completely so that WeirdInt and QueryService are not exposed to the 'client' code such that you don't need to include any headers which declare them in the client code, then I doubt the approach you take will be able to benefit from any magic.
When I've done this before, my first step has been to use the pimpl idiom so that your header contains no implementation details as follows:
QueryServiceWrapper.h
class QueryServiceWrapperImpl;
class QueryServiceWrapper
{
public:
QueryServiceWrapper();
virtual ~QueryServiceWrapper();
int getId();
private:
QueryServiceWrapperImpl impl_;
};
and then in the definition, you can put the implementation details, safe in the knowledge that it will not leach out to any downstream code:
QueryServiceWrapper.cpp
struct QueryServiceWrapperImpl
{
public:
QueryService svc_;
};
// ...
int QueryServiceWrapper::getValue()
{
return impl_->svc_.getId().getValue();
}
Without knowing what different methods need to be employed to do the conversion, it's difficult add too much more here, but you could certainly use template functions to do conversion of the most popular types.
The downside here is that you'd have to implement everything yourself. This could be a double edged sword as it's then possible to implement only that functionality that you really need. There's generally no point in wrapping functionality that is never used.
I don't know of a 'silver bullet' that will implement the functions - or even empty wrappers on the functions. I've normally done this by a combination of shell scripts to either create the empty classes that I want or taking a copy of the header and using text manipulation using sed or Perl to change original types to the new types for the wrapper class.
It's tempting in these cases to use public inheritance to enable access to the base functions while allowing functions to be overridden. However, this is not applicable in your case as you want to change return types (not sufficient for an overload) and (presumably) you want to prevent exposure of the original Weird types.
The way forward here has to be to use aggregation although in such as case there is no way you can easily avoid re-implementing (some of) the interfaces unless you are prepared to automate the creation of the class (using code generation) to some extent.
more complex approach is to introduce a required number of facade classes over original QueryService, each of which has a limited set of functions for one particular query or query-type. I don't know that your particular QueryService do, so here is an imaginary example:
suppose the original class have a lot of weired methods worked with strange types
struct OriginQueryService
{
WeirdType1 query_for_smth(...);
WeirdType1 smth_related(...);
WeirdType2 another_query(...);
void smth_related_to_another_query(...);
// and so on (a lot of other function-members)
};
then you may write some facade classes like this:
struct QueryFacade
{
OriginQueryService& m_instance;
QueryFacade(OriginQueryService* qs) : m_instance(*qs) {}
// Wrap original query_for_smth(), possible w/ changed type of
// parameters (if you'd like to convert 'em from C++ native types to
// some WeirdTypeX)...
DesiredType1 query_for_smth(...);
// more wrappers related to this particular query/task
DesiredType1 smth_related(...);
};
struct AnotherQueryFacade
{
OriginQueryService& m_instance;
AnotherQueryFacade(OriginQueryService* qs) : m_instance(*qs) {}
DesiredType2 another_query(...);
void smth_related_to_another_query(...);
};
every method delegate call to m_instance and decorated w/ input/output types conversion in a way you want it. Types conversion can be implemented as #Jack describe in his post. Or you can provide a set of free functions in your namespace (like Desired fromWeird(const Weired&); and Weired toWeired(const Desired&);) which would be choosen by ADL, so if some new type arise, all that you have to do is to provide overloads for this 2 functions... such approach work quite well in boost::serialization.
Also you may provide a generic (template) version for that functions, which would call getValue() for example, in case if lot of your Weired types has such member.
EDIT: To be clear—right off the bat—this is a question about the linguistic abilities of a modern C++ compiler. Not a question about a specific goal. It's hard to describe such an abstract concept without clarifying this first and I've realized that some of the confusion revolves around what is commonly done rather than what can possibly be done. This is a very abstract question. Nothing here will compile and this is on purpose. Likewise, I'm not asking how to make this specific case work, but I'm asking if there's a way to get C++ to recognize what I would like to do (via templating or some kind of auto->decltype trick most likely if even possible).
I'm not exactly new to C++, but certainly not an expert. This is a fundamental problem that I've been struggling with since I've rediscovered the power of the language. The end goal here is to elegantly (and with as little code as possible) forward proper polymorphic return values based on calling context. For example...
class A {
public:
A& foo() {
// do something mutant fooish
return *this;
};
};
class B: public A {
public:
B& bar() {
// do something mutant barish
return *this;
};
};
int main(int argc, char** argv) {
B yarp;
yarp.foo().bar();
};
Compile error. Makes sense, C++ is designed to assume that you know nothing about what you're doing (which makes it highly optimizable but sometimes a pain... a high-level-mid-level OOP language).
Obvioiusly C++ compilers have gotten to the point where they're not only aware of what you are asking for (the A().foo() works and B().foo() works scenario), but also in what context your asking for it in (hence auto yarp = B() in C++11, the compiler knows that yarp is an instance of B). Is there a way to leverage this elegantly without having to reproduce a bunch of "using" statements or wrapped methods (which strangely don't get optimized out according to disassemble of gcc binaries)?
So is there a trick here? Something I simply haven't learned online. An auto -> decltype trick or a templating trick? Example:
class A {
public:
template <typename R>
R& foo() {
// do something fooish
return (R&)*this;
};
};
class B: public A {
public:
using A::foo<A>; // << even this would be better than nothing (but no where near optimum)
B& bar() {
// do something barish
return *this;
};
};
Something even simpler? If you expand this concept to operators of a proxy template class meant for reference counting and gc deallocation, it becomes clear how problematic this becomes. Thanks in advance for any help (oh, and first post on stackoverflow, so if I got any formatting wrong or you have suggestions for a better structured post, apologies around and please point them out).
The obvious solution would be to just seperate it out into two lines:
yarp.foo();
yarp.bar();
or, alternatively, use static_cast's to get back a reference to B&, so
static_cast<B&>(yarp.foo()).bar();
Agreed, that's a little bit more verbose but chaining multiple member-function calls in a heirarchy in one line together like this is pretty unusual syntax for C++. It just doesn't come up a whole lot, so the language doesn't support that idiom terribly well. I have never come across a situation where I ran into this issue yet.
If you want to design some chainable functionality, there are other, better idioms you can use. One example is Boost's Range Adaptors that overload operator| to achieve chaining.
EDIT: Another option is to overload foo() in B&:
class B: public A {
public:
B& foo() { A::foo(); return *this; }
B& bar() {
// do something mutant barish
return *this;
};
};
I don't think there is a auto type detection since compiler even doesn't know what classes will inherit A.
And in your second trial, C++ forbid using a template specialization. So that won't compile.
I think there is another trick you could try is to make A a template
template <typename FinalType>
class A {
public:
FinalType& foo() {
// do something fooish
return static_cast<FinalType&>(*this);
};
};
class B: public A<B> {
public:
B& bar() {
// do something barish
return *this;
};
};
Erm you declare a instance of class B which has no method foo - so no wonder there is a compile error - did you mean
yarp.bar().foo();
I have a simple, low-level container class that is used by a more high-level file class. Basically, the file class uses the container to store modifications locally before saving a final version to an actual file. Some of the methods, therefore, carry directly over from the container class to the file class. (For example, Resize().)
I've just been defining the methods in the file class to call their container class variants. For example:
void FileClass::Foo()
{
ContainerMember.Foo();
}
This is, however, growing to be a nuisance. Is there a better way to do this?
Here's a simplified example:
class MyContainer
{
// ...
public:
void Foo()
{
// This function directly handles the object's
// member variables.
}
}
class MyClass
{
MyContainer Member;
public:
void Foo()
{
Member.Foo();
// This seems to be pointless re-implementation, and it's
// inconvenient to keep MyContainer's methods and MyClass's
// wrappers for those methods synchronized.
}
}
Well, why not just inherit privatly from MyContainer and expose those functions that you want to just forward with a using declaration? That is called "Implementing MyClass in terms of MyContainer.
class MyContainer
{
public:
void Foo()
{
// This function directly handles the object's
// member variables.
}
void Bar(){
// ...
}
}
class MyClass : private MyContainer
{
public:
using MyContainer::Foo;
// would hide MyContainer::Bar
void Bar(){
// ...
MyContainer::Bar();
// ...
}
}
Now the "outside" will be able to directly call Foo, while Bar is only accessible inside of MyClass. If you now make a function with the same name, it hides the base function and you can wrap base functions like that. Of course, you now need to fully qualify the call to the base function, or you'll go into an endless recursion.
Additionally, if you want to allow (non-polymorphical) subclassing of MyClass, than this is one of the rare places, were protected inheritence is actually useful:
class MyClass : protected MyContainer{
// all stays the same, subclasses are also allowed to call the MyContainer functions
};
Non-polymorphical if your MyClass has no virtual destructor.
Yes, maintaining a proxy class like this is very annoying. Your IDE might have some tools to make it a little easier. Or you might be able to download an IDE add-on.
But it isn't usually very difficult unless you need to support dozens of functions and overrides and templates.
I usually write them like:
void Foo() { return Member.Foo(); }
int Bar(int x) { return Member.Bar(x); }
It's nice and symmetrical. C++ lets you return void values in void functions because that makes templates work better. But you can use the same thing to make other code prettier.
That's delegation inheritance and I don't know that C++ offers any mechanism to help with that.
Consider what makes sense in your case - composition (has a) or inheritance (is a) relationship between MyClass and MyContainer.
If you don't want to have code like this anymore, you are pretty much restricted to implementation inheritance (MyContainer as a base/abstract base class). However you have to make sure this actually makes sense in your application, and you are not inheriting purely for the implementation (inheritance for implementation is bad).
If in doubt, what you have is probably fine.
EDIT: I'm more used to thinking in Java/C# and overlooked the fact that C++ has the greater inheritance flexibility Xeo utilizes in his answer. That just feels like nice solution in this case.
This feature that you need to write large amounts of code is actually necessary feature. C++ is verbose language, and if you try to avoid writing code with c++, your design will never be very good.
But the real problem with this question is that the class has no behaviour. It's just a wrapper which does nothing. Every class needs to do something other than just pass data around.
The key thing is that every class has correct interface. This requirement makes it necessary to write forwarding functions. The main purpose of each member function is to distribute the work required to all data members. If you only have one data member, and you've not decided yet what the class is supposed to do, then all you have is forwarding functions. Once you add more member objects and decide what the class is supposed to do, then your forwarding functions will change to something more reasonable.
One thing which will help with this is to keep your classes small. If the interface is small, each proxy class will only have small interface and the interface will not change very often.
Given the following template:
template <typename T>
class wrapper : public T {};
What visible differences in interface or behaviour are there between an object of type Foo and an object of type wrapper<Foo>?
I'm already aware of one:
wrapper<Foo> only has a nullary constructor, copy constructor and assignment operator (and it only has those if those operations are valid on Foo). This difference may be mitigated by having a set of templated constructors in wrapper<T> that pass values through to the T constructor.
But I'm not sure what other detectable differences there might be, or if there are ways of hiding them.
(Edit) Concrete Example
Some people seem to be asking for some context for this question, so here's a (somewhat simplified) explanation of my situation.
I frequently write code which has values which can be tuned to adjust the precise performance and operation of the system. I would like to have an easy (low code overhead) way of exposing such values through a config file or the user interface. I am currently writing a library to allow me to do this. The intended design allows usage something like this:
class ComplexDataProcessor {
hotvar<int> epochs;
hotvar<double> learning_rate;
public:
ComplexDataProcessor():
epochs("Epochs", 50),
learning_rate("LearningRate", 0.01)
{}
void process_some_data(const Data& data) {
int n = *epochs;
double alpha = *learning_rate;
for (int i = 0; i < n; ++i) {
// learn some things from the data, with learning rate alpha
}
}
};
void two_learners(const DataSource& source) {
hotobject<ComplexDataProcessor> a("FastLearner");
hotobject<ComplexDataProcessor> b("SlowLearner");
while (source.has_data()) {
a.process_some_data(source.row());
b.process_some_data(source.row());
source.next_row();
}
}
When run, this would set up or read the following configuration values:
FastLearner.Epochs
FastLearner.LearningRate
SlowLearner.Epochs
SlowLearner.LearningRate
This is made up code (as it happens my use case isn't even machine learning), but it shows a couple of important aspects of the design. Tweakable values are all named, and may be organised into a hierarchy. Values may be grouped by a couple of methods, but in the above example I just show one method: Wrapping an object in a hotobject<T> class. In practice, the hotobject<T> wrapper has a fairly simple job -- it has to push the object/group name onto a thread-local context stack, then allow the T object to be constructed (at which point the hotvar<T> values are constructed and check the context stack to see what group they should be in), then pop the context stack.
This is done as follows:
struct hotobject_stack_helper {
hotobject_stack_helper(const char* name) {
// push onto the thread-local context stack
}
};
template <typename T>
struct hotobject : private hotobject_stack_helper, public T {
hotobject(const char* name):
hotobject_stack_helper(name) {
// pop from the context stack
}
};
As far as I can tell, construction order in this scenario is quite well-defined:
hotobject_stack_helper is constructed (pushing the name onto the context stack)
T is constructed -- including constructing each of T's members (the hotvars)
The body of the hotobject<T> constructor is run, which pops the context stack.
So, I have working code to do this. There is however a question remaining, which is: What problems might I cause for myself further down the line by using this structure. That question largely reduces to the question that I'm actually asking: How will hotobject behave differently from T itself?
Strange question, since you should be asking questions about your specific usage ("what do I want to do, and how does this help me or hurt me"), but I guess in general:
wrapper<T> is not a T, so:
It can't be constructed like a T. (As you note.)
It can't be converted like a T.
It loses access to privates T has access to.
And I'm sure there are more, but the first two cover quite a bit.
Suppose you have:
class Base {};
class Derived : Base {};
Now you can say:
Base *basePtr = new Derived;
However, you cannot say:
wrapper<Base> *basePtr = new wrapper<Derived>();
That is, even though their type parameters may have an inheritance relationship, two types produced by specialising a template do not have any inheritance relationship.
A reference to an object is convertible (given access) to a reference to a base class subobject. There is syntactic sugar to invoke implicit conversions allowing you to treat the object as an instance of the base, but that's really what's going on. No more, no less.
So, the difference is not hard to detect at all. They are (almost) completely different things. The difference between an "is-a" relationship and a "has-a" relationship is specifying a member name.
As for hiding the base class, I think you inadvertently answered your own question. Use private inheritance by specifying private (or omitting public for a class), and those conversions won't happen outside the class itself, and no other class will be able to tell that a base even exists.
If your inherited class has its own member variables (or at least one), then
sizeof(InheritedClass) > sizeof(BaseClass)
Is there a side effect in doing this:
C code:
struct foo {
int k;
};
int ret_foo(const struct foo* f){
return f.k;
}
C++ code:
class bar : public foo {
int my_bar() {
return ret_foo( (foo)this );
}
};
There's an extern "C" around the C++ code and each code is inside its own compilation unit.
Is this portable across compilers?
This is entirely legal. In C++, classes and structs are identical concepts, with the exception that all struct members are public by default. That's the only difference. So asking whether you can extend a struct is no different than asking if you can extend a class.
There is one caveat here. There is no guarantee of layout consistency from compiler to compiler. So if you compile your C code with a different compiler than your C++ code, you may run into problems related to member layout (padding especially). This can even occur when using C and C++ compilers from the same vendor.
I have had this happen with gcc and g++. I worked on a project which used several large structs. Unfortunately, g++ packed the structs significantly looser than gcc, which caused significant problems sharing objects between C and C++ code. We eventually had to manually set packing and insert padding to make the C and C++ code treat the structs the same. Note however, that this problem can occur regardless of subclassing. In fact we weren't subclassing the C struct in this case.
I certainly not recommend using such weird subclassing. It would be better to change your design to use composition instead of inheritance.
Just make one member
foo* m_pfoo;
in the bar class and it will do the same job.
Other thing you can do is to make one more class FooWrapper, containing the structure in itself with the corresponding getter method. Then you can subclass the wrapper. This way the problem with the virtual destructor is gone.
“Never derive from concrete classes.” — Sutter
“Make non-leaf classes abstract.” — Meyers
It’s simply wrong to subclass non-interface classes. You should refactor your libraries.
Technically, you can do what you want, so long as you don’t invoke undefined behavior by, e. g., deleting a pointer to the derived class by a pointer to its base class subobject. You don’t even need extern "C" for the C++ code. Yes, it’s portable. But it’s poor design.
This is perfectly legal, though it might be confusing for other programmers.
You can use inheritance to extend C-structs with methods and constructors.
Sample :
struct POINT { int x, y; }
class CPoint : POINT
{
public:
CPoint( int x_, int y_ ) { x = x_; y = y_; }
const CPoint& operator+=( const POINT& op2 )
{ x += op2.x; y += op2.y; return *this; }
// etc.
};
Extending structs might be "more" evil, but is not something you are forbidden to do.
Wow, that's evil.
Is this portable across compilers?
Most definitely not. Consider the following:
foo* x = new bar();
delete x;
In order for this to work, foo's destructor must be virtual which it clearly isn't. As long as you don't use new and as long as the derived objectd don't have custom destructors, though, you could be lucky.
/EDIT: On the other hand, if the code is only used as in the question, inheritance has no advantage over composition. Just follow the advice given by m_pGladiator.
This is perfectly legal, and you can see it in practice with the MFC CRect and CPoint classes. CPoint derives from POINT (defined in windef.h), and CRect derives from RECT. You are simply decorating an object with member functions. As long as you don't extend the object with more data, you're fine. In fact, if you have a complex C struct that is a pain to default-initialize, extending it with a class that contains a default constructor is an easy way to deal with that issue.
Even if you do this:
foo *pFoo = new bar;
delete pFoo;
then you're fine, since your constructor and destructor are trivial, and you haven't allocated any extra memory.
You also don't have to wrap your C++ object with 'extern "C"', since you're not actually passing a C++ type to the C functions.
I don't think it is necessarily a problem. The behaviour is well defined, and as long as you are careful with life-time issues (don't mix and match allocations between the C++ and C code) will do what you want. It should be perfectly portable across compilers.
The problem with destructors is real, but applies any time the base class destructor isn't virtual not just for C structs. It is something you need to be aware of but doesn't preclude using this pattern.
It will work, and portably BUT you cannot use any virtual functions (which includes destructors).
I would recommend that instead of doing this you have Bar contain a Foo.
class Bar
{
private:
Foo mFoo;
};
I don't get why you don't simply make ret_foo a member method. Your current way makes your code awfully hard to understand. What is so difficult about using a real class in the first place with a member variable and get/set methods?
I know it's possible to subclass structs in C++, but the danger is that others won't be able to understand what you coded because it's so seldom that somebody actually does it. I'd go for a robust and common solution instead.
It probably will work but I do not believe it is guaranteed to. The following is a quote from ISO C++ 10/5:
A base class subobject might have a layout (3.7) different from the layout of a most derived object of the same type.
It's hard to see how in the "real world" this could actually be the case.
EDIT:
The bottom line is that the standard has not limited the number of places where a base class subobject layout can be different from a concrete object with that same Base type. The result is that any assumptions you may have, such as POD-ness etc. are not necessarily true for the base class subobject.
EDIT:
An alternative approach, and one whose behaviour is well defined is to make 'foo' a member of 'bar' and to provide a conversion operator where it's necessary.
class bar {
public:
int my_bar() {
return ret_foo( foo_ );
}
//
// This allows a 'bar' to be used where a 'foo' is expected
inline operator foo& () {
return foo_;
}
private:
foo foo_;
};