Accessing methods of an object put inside a class - c++

A class A possesses an instance c of a class C. Another class B has to modify c through C::setBlah(); method.
Is it bad to create an accessor C getC(); in A and then use A.getC().setBlah() ?
Or should I create a method A::setBlah(); that would call C::setBlah(); ? Isn't it annoying if there are several methods like that ?

As with most "is it bad to do X?" questions, the answer is that it depends entirely on a given situation.
Sometimes it might be a really bad idea to have a getC() sort of function because it breaks encapsulation. Other times it might be completely fine because encapsulation of that detail might be irrelevant, and writing a lot of wrapper functions increases the amount of code that you have to write.
Pick whichever makes the most sense for the given situation. In code that I've written, I've taken both approaches.
If you do go the getC() route, do make sure you return a reference; otherwise you'll be modifying a copy which doesn't sound like what you want. Or, you might consider making A::c public so that you don't need a function at all.
A third option to consider would be inheritance from C, which removes the need for getC() or wrapper functions in A.

A Method C getC(); creates a copy of c, so calling A.getC().setBlah() would modify the copy of c, not the c of A.

If C has many similar methods to be called by classes outside A, I would definitely not add these to A. I prefer to keep interfaces as minimal as possible. If these changes are related and are done together, you may add a dedicated single function to A to execute all calls to C at once and logically collect all these changes under an intuitive name.
Such a setup also raises the question: why does B need to touch A's member C? Maybe your design is not quite right - should C be a member of B rather than A?

Related

Inheritance, overriding, and virtual functions to avoid repeated code

I have three classes, A, B, and C. B and C are derived from A. Both B and C need to implement a method F. The code in B.F() is a subset of C.F().
Is it a good way declare A.F() as a virtual function and define B.F() and C.F()? There would be the same code in 2 methods, which I would like to avoid. What are the other
possibilities?
Define A.F() with the common code and override it in C.F(). While overriding how can the output of A.F() be used in C.F(), so that repeated code can be avoided?
I guess it's not the best thing to do. If you can avoid code rewriting - sure, do it.
It would be better to define F() in A, as you've said, with the common code for both B and C, and then override it in C.F(), using A::F() call in overriden function. I mean, with this you can firstly execute parent method A.F(), and then go with new extra logic. If you're inheriting B from A, you shouldn't then bother about this method in B at all.
Note that from this point of view, the order will be important. If you want parent code execution to be first, then call A::F() before your additional logic. It's on you to decide, what order to choose, though.
EDIT
I will add a link with a good example for you, if you don't know how to call parent method code inside child method. Take a look, and have a nice time.

How could I avoid diamond inheritance?

I am currently working on a C++ design where I have this inheritance structure:
A
/ \
B C
Class A does the computations that are common to both classes B and C, and classes B and C are two different ways of initializing A.
I'd like to add some sort of hybrid initialization, i.e. a class D that would use methods from B and C.
However, I'd need to use diamond inheritance to be able to access B::init() and C::init() to set up the attributes of D.
I know I can avoid diamond problems using virtual inheritance, but I get runtime errors that I don't have when I copy manually the methods. Moreover, I have problems when trying to instantiate the classes B and C, and a colleague advised me to never use diamond inheritance in my designs.
Therefore, I'd like to find some kind of "clean" workaround, which I have not been able to do.
I could put all the initialization routines in class A, but for the moment they are separated nicely and I'd like to avoid having one big class where I can't really separate the distinct groups of functions of the classes B and C. EDIT after answer: This is what I chose, using different cpp files to split my "big" class into logical groups of methods.
I could also remove the inheritance links and replace them with friendship, where the methods of B and C are static and work on a pointer of type A*. This way, I could call B::init(A* a) and C::init(A* a) from D::init(A* a). However, I'd have to replace all the uses of _fooAttribute by a->_fooAttribute, which is a bit cumbersome and does not seem right.
What would you recommend ?
If your design calls for diamond inheritance, then that is what you need to do. People treat it as a "must not use" feature of C++, but the truth of the matter is that it is there, it is fully defined (if somewhat complex to understand), and if your problem space calls for it, you should use it.
In particular, I was not able to understand whether this is, indeed, a diamond inheritance. In particular, does it make sense for the A inside B and the A inside C to be the same instance of A? From your question it would appear that it is not. That Both B and C has a certain, different, way it makes sense to initialize A. If that is the case, this is not a diamond inheritance. Just make sure that B and C inherit A in a non-virtual inheritance.
With that said, make sure this is, indeed, what your design calls for. Can you honestly say that B is a A? That C? Can you honestly say that D is both a B and a C? If not, maybe making A a member of B, C or both, or making B or C members of D would make more sense.
If the only reason you are inheriting from A is as a way to extend A's provided methods, then consider simply making those methods a member of A. As stated above, while reducing code duplication is a worthy cause, the design should make sure that inheritance relationship is a is a relationship. Deviating from that is asking for trouble.
Inheritance is an "is a" relationship. If B is an A, then you're good. The same applies to C. From your description, you do not have this relationship. Instead, you have a utility class (A) that does computations. You might want to make this have static methods as it shouldn't need to store any data in itself, if it's truly a utility. There's nothing wrong with passing A an instance of B or C and having it access the properties that it needs using B->fooAttribute. However, you will probably want both B and C to implement a common interface so you don't have to know which one you're looking at.

Design pattern for nested functions in C++

I have two Class A, B.
For A, I have two method callB(), and checksomethinginB().
For B, I have one method execute().
I use them like:
A _a;
_a.callB(); //inside the function, B object _b will be created
//after _b created, in another place, _b will execute _b.execute().
_b.execute()
{
// I want to use A method checksomethinginB()
}
So I don't know a good way to use A method in B, what I can create is to use static functions, but I think there maybe better way, thanks for your suggestion!!
Either pass the correct instance of A to the constructor of B, or pass it along whenever needed.
If checksomethinginB doesn't need any state in A then it can be static of course.
Without seeing the class details and without an explanation of what your classes actually do, you could consider these options:
If there is commonality between class A and B you could consider deriving one from the other. This should not be used unless there is a good reason and not just to enable you to do what you want
Modify the function signature of B:execute to take a parameter argument that is an instance of class A (or pointer to or reference to an instance of A) so that you can call the A::checksomethinginB()
Make the function static as you suggest - bear in mind that this is not possible if checksomethinginB() requires access to the non-static member variables of A
There are possibly better alternatives, but without more details about your classes and functionality requirements it is hard to say
I'm not really sure why do you want a function in class A that operates on class B - I would move A::checksomethinginB() to B::checksomething(). From here, I see two (+1) possibilities:
If A::checksomethinginB / B::checksomething does not use any state from A, then you are done..
If it does, then it actually uses A in it's code, so you need to give him one: probably pass a reference to it.
If it only uses A's static parts, you can just use them with A::staticSomethingNotMentionedBefore directly.

Should I use an API/ABC when designing a class used by several in C++?

I am about to add a class X that will be used by my three previously designed classes (A, B and C).
The new class X will contain data and functions for new features as well as provide services to the classes that use it to hide lower layers. The problem is that A, B and C will use class X quite differently, that is, use different functions of it.
My question is if I should provide an API (or Abstract Base Class in C++) for the new class X or not. If I should, should that API be per X class or per A, B and C class? I have read somewhere that an API is sometimes more closely related to that caller that the class that implements it. If I do provide one API for each caller, the API will only contain the functions that the particular caller needs.
Or should I just create a normal C++ class and let the callers use a subset of the public functions of X in each of A, B and C, although they "technically" can use them all? The functions of class X are not very likely to change neither is the need to create a similar class to X.
If I'm not completely lost in object oriented programming, one reason for providing an interface/API for a class is that code that use the interface/API doesn't need to change if you add another subclass since the caller works on the interface name and uses dynamic binding to resolve the correct subclass type.
Best regards and please let me know if anything is unclear and I'll try to answer that as quickly as possible.
Thanks,
Tomas
Are you sure all these functions belong to the same class X? Think about separating different functionality into different classes:
http://en.wikipedia.org/wiki/Low-Coupling_/_High-Cohesion_pattern
But without knowing what the functions of X are it is difficult to help further.
If things are unlikely to change then it's probably not worth the extra effort.
If you decide to, though, the question is whether new classes would implement all or just part of the functionality. For example, do they share backend storage, so all would need to be updated at once (in which case there is no point in splitting), or do they relate to entirely separate concerns in which case splitting (as suggested by #GarethOwen) is probably the way to go.

C++ : implications of making a method virtual

Should be a newbie question...
I have existing code in an existing class, A, that I want to extend in order to override an existing method, A::f().
So now I want to create class B to override f(), since I don't want to just change A::f() because other code depends on it.
To do this, I need to change A::f() to a virtual method, I believe.
My question is besides allowing a method to be dynamically invoked (to use B's implementation and not A's) are there any other implications to making a method virtual? Am I breaking some kind of good programming practice? Will this affect any other code trying to use A::f()?
Please let me know.
Thanks,
jbu
edit: my question was more along the lines of is there anything wrong with making someone else's method virtual? even though you're not changing someone else's implementation, you're still having to go into someone's existing code and make changes to the declaration.
If you make the function virtual inside of the base class, anything that derives from it will also have it virtual.
Once virtual, if you create an instance of A, then it will still call A::f.
If you create an instance of B and store it in a pointer of type A*. And then you call A*::->f, then it will call B's B::f.
As for side effects, there probably won't be any side effects, other than a slight (unnoticeable) performance loss.
There is a very small side effect as well, there could be a class C that also derives from A, and it may implement C::f, and expect that if A*::->f was called, then it expects A::f to be called. But this is not very common.
But more than likely, if C exists, then it does not implement C::f at all, and in which case everything is fine.
Be careful though, if you are using an already compiled library and you are modifying it's header files, what you are expecting to work probably will not. You will need to recompile the header and source files.
You could consider doing the following to avoid side effects:
Create a type A2 that derives from A and make it's f virtual
Use pointers of type A2 instead of A
Derive B from type A2.
In this way anything that used A will work in the same way guaranteed
Depending on what you need you may also be able to use a has-a relationship instead of a is-a.
There is a small implied performance penalty of a vtable lookup every time a virtual function is called. If it were not virtual, function calls are direct, since the code location is known at compile time. Wheras at runtime, a virtual function address must be referenced from the vtable of the object you're calling upon.
To do this, I need to change A::f() to
a virtual method, I believe.
Nope, you do not need to change it to a virtual method in order to override it. However, if you are using polymorphism you need to, i.e. if you have a lot of different classes deriving from A but stored as pointers to A.
There's also a memory overhead for virtual functions because of the vtable (apart from what spoulson mentioned)
There are other ways of accomplishing your goal. Does it make sense for B to be an A? For example, it makes sense for a Cat to be an Animal, but not for a Cat to be a Dog. Perhaps both A and B should derive from a base class, if they are related.
Is there just common functionality you can factor out? It sounds to me like you'll never be using these classes polymorphically, and just want the functionality. I would suggest you take that common functionality out and then make your two separate classes.
As for cost, if you're using A ad B directly, the compile will by-pass any virtual dispatching and just go straight to the functions calls, as if they were never virtual. If you pass a B into a place expecting `A1 (as a reference or pointer), then it will have to dispatch.
There are 2 performance hits when speaking about virtual methods.
vtable dispatching, its nothing to really worry about
virtual functions are never inlined, this can be much worse than the previous one, function inlining is something that can really speed things in some situations, it can never happen with a virtual function.
How kosher it is to change somebody else's code depends entirely on the local mores and customs. It isn't something we can answer for you.
The next question is whether the class was designed to be inherited from. In many cases, classes are not, and changing them to be useful base classes, without changing other aspects, can be tricky. A non-base class is likely to have everything private except the public functions, so if you need to access more of the internals in B you'll have to make more modifications to A.
If you're going to use class B instead of class A, then you can just override the function without making it virtual. If you're going to create objects of class B and refer to them as pointers to A, then you do need to make f() virtual. You also should make the destructor virtual.
It is good programming practise to use virtual methods where they are deserved. Virtual methods have many implications as to how sensible your C++ Class is.
Without virtual functions you cannot create interfaces in C++. A interface is a class with all undefined virtual functions.
However sometimes using virtual methods is not good. It doesn't always make sense to use a virtual methods to change the functionality of an object, since it implies sub-classing. Often you can just change the functionality using function objects or function pointers.
As mentioned a virtual function creates a table which a running program will reference to check what function to use.
C++ has many gotchas which is why one needs to be very aware of what they want to do and what the best way of doing it is. There aren't as many ways of doing something as it seems when compared to runtime dynamic OO programming languages such as Java or C#. Some ways will be either outright wrong, or will eventually lead to undefined behavior as your code evolves.
Since you have asked a very good question :D, I suggest you buy Scott Myer's Book: Effective C++, and Bjarne Stroustrup's book: The C++ Programming Language. These will teach you the subtleties of OO in C++ particularly when to use what feature.
If thats the first virtual method the class is going to have, you're making it no longer a POD. This can break things, although the chances for that are slim.
POD: http://en.wikipedia.org/wiki/Plain_old_data_structures