now before you guys start raging, here me out. Yes, i recognize that it is actually intended for friendship to not be inherited, i'm just trying to find some way to get something similar to it. Here is my situation (no real code, just theory). i'm working on a simple abstract game engine framework, and at first, i was just going to do the straightforward object oriented/ inheritance approach of breaking object types down. Now, it sounded really nice on paper, taking entities and breaking them into subcategories of physics, animated, and unmoving scenary and all it's subcategories. This however, became a hazardous, difficult to work with mess of entirely different objects and quite a bit of dangerous casting that could easily cause problems should i miss on something i needed to enforce instead of the compiler, which is always a good sign that there is a better solution.
So, I propose a different method of abstractly representing objects. I wish for there to be one entity class that all entities derive from which contain a vector, or some other dynamically growable array that works best, That will contain objects i'd call behaviors. The behaviors would be updated after a specified amount of time, which will affect the members of the object specified. Here are some examples.
class Force : behavior;
/*this would be a force, added to the behavior list and apply a constant
acceleration vector to the object until removed from the behavior list. (or
it's lifetime is exhausted) */
class attackThought : behavior;
/* For an ai, this would change how it reacts to a scenario by replacing or
even adding actions that it should perform given the change in position
or environment at update.*/
class animation : behavior;
/* You could create an animation, specify the animation that it is to perform,
add it to the behavior list, and during the time update, it will adjust the
vertex buffer accordingly, removing itself from the list when the animation
is done */
The problem is, i want to derive from a base behavior class, that implements some of it's virtual functions in different ways that will mostly change private members of the entity objects, (such as an objects vertex buffer). i don't want to have to manipulate too much of the basic entity code so that it can, (for the most part), be treated similarly to other objects, I only want their behaviors to be entirely manipulable/derivable. can anyone think of a way to make this system work in c++, cause i think it might be really cool :P.
btw, by way of friendship, i mean the base class behavior friending some derived entity class which can effect it's private members. For example, let's say i have a model class that derives from entity, and i want to friend a derived class of behavior called animation, and then later derive a class from model to a more specific type of object for some reason, how can an animation object manipulate the private members of this new model deriving object.
or can it? opinions on how viable this approach might be are also welcome, (as long as they actually contain critcism).
I have seen through the years that there are 2 different points of view on friendship and how it affects encapsulation:
It helps improve encapsulation by not making members public to everybody, and only making them accessible to a controlled subset of entities.
It reduces encapsulation for the obvious classic reasons that the object should be self contained and should be the only entity to modify its internal parts, etc.
I tend to avoid using friendship and try to work around it. I prefer to encapsulate everything, not just to make it private, but to be able to change how its implemented internally without affecting the users of the class. If you want a base class to be able to modify the attributes of a derived class, maybe you could consider using a Template Method design pattern. Whereby the base class orchestrates calling methods on the derived classes, and be sure to have generic, abstract manipulation methods defined in the base class.
As for making all the attributes of a class public "just in case", (sounds very dangerous) I think it would be better to start off making them all private, and consider making individual attributes public as the needs arise.
Related
I realise that providing a method which returns a pointer to a private method breaks encapsulation, and exposes the field to anyone who uses the class. However, suppose the following:
You have a class which calls the method of another class (which expects a pointer to some private field), and the address of the private member is passed as a parameter to this method.
As far as I can see, as long as the private member's address is only exposed in a way controlled by the developer of the class, this doesn't break encapsulation (i.e. the developer knows exactly how it's going to be used). Of course, the method called could (assuming you didn't write it) expose the private member, but do we need to look that far ahead? I've seen this done countless times, so I guess it's not the result of bad design practises?
Is it bad practise to write method which take pointers to private members of other classes and modify them? Should each class only "look out for themselves"?
It would be a bad design because most classes have getters and setters to read and write to the object. So if that function needs to read and write then it should ask for object reference, not for pointer to any private memeber.
And in most of cases when function needs a reference for variable, it asks for reference to a constant value.
I realise that providing a method which returns a pointer to a private method breaks encapsulation, and exposes the field to anyone who uses the class.
This is not true to begin with.
A class that has a method that returns a pointer as part of its interface is absolutely fine, and the fact that it returns a member variable is an implementation detail that the outside world does not need to know.
Now, that being said, it is difficult to design a sane class interface that involves functions that return non-owning pointers, so it's something we tend to avoid.
Edit as far as the second part of the question goes:
Any class is supposed to sanely handle any possible permutation of usage of its public interface (including de-referencing any returned pointers). What or who uses the public interface is supposed to be entirely irrelevant, and you should assume that all users of the class will make use of the entire public API.
If you have parts of the class that you only want to make available to specific types or functions, then that's exactly what friend is for. But this has nothing to do with pointers to members, it applies to any and all parts of the class.
Is there any efficiency disadvantage associated with deep inheritance trees (in c++), i.e, a large set of classes A, B, C, and so on, such that B extends A, C extends B, and so one. One efficiency implication that I can think of is, that when we instantiate the bottom most class, say C, then the constructors of B and A are also called, which will have performance implications.
Let's enumerate the operations we should consider:
Construction/destruction
Each constructor/destructor will call its base class equivalents. However, as James McNellis pointed out, you were obviously going to do that work anyway. You didn't derived from A just because it was there. So the work is going to get done one way or another.
Yes, it will involve a few more function calls. But function call overhead will be nothing compared to the actual work any significantly deep class hierarchy will have to actually do. If you're at the point where function call overhead is actually important for performance, I would strongly suggest that calling constructors at all is probably not what you want to be doing in that code.
Object Size
In general, the overhead for a derived class is nothing. The overhead for virtual members is a pointer or for virtual inheritance.
Member Function Calls, Static
By this, I mean calling non-virtual member functions, or calling virtual member functions with class names (ClassName::FunctionName syntax). Both of these allow the compiler to know at compile time which function to call.
The performance of this is invariant with the size of the hierarchy, since it's compile-time determined.
Member Function Calls, Dynamic
This is calling virtual functions with the full and complete expectation of runtime calls.
Under most sane C++ implementations, this is invariant with the size of the object hierarchy. Most implementations use a v-table for each class. Each object has a v-table pointer as a member. For any particular dynamic call, the compiler accesses the v-table pointer, picks out the method, and calls it. Since the v-table is the same for each class, it won't be any slower for a class that has a deep hierarchy than one with a shallow one.
Virtual inheritance plays a bit with this.
Pointer Casts, Static
This refers to static_cast or any equivalent operation. This means the implicit cast from a derived class to a base class, the explicit use of static_cast or C-style casts, etc.
Note that this technically includes reference casting.
The performance of static casts between classes (up or down) is invariant with the size of the hierarchy. Any pointer offsets will be compile-time generated. This should be true for virtual inheritance as well as non-virtual inheritance, but I'm not 100% certain of that.
Pointer Casts, Dynamic
This obviously refers to the explicit use of dynamic_cast. This is typically used when casting from a base class to a derived one.
The performance of dynamic_cast will likely change for a large hierarchy. But sane implementations should only check the classes between the current class and the requested one. So it's simply linear in the number of classes between the two, not linear in the number of classes in the hierarchy.
Typeof
This means the use of the typeof operator to fetch the std::type_info object associated with an object.
The performance of this will be invariant with the size of the hierarchy. If the class is a virtual one (has virtual functions or virtual base classes), then it will simply pull it out of the vtable. If it's not virtual, then it's compile-time defined.
Conclusion
In short, most operations are invariant with the size of the hierarchy. But even in the cases where it has an impact, it's not a problem.
I'd be more concerned with some design ethic where you felt the need to build such a hierarchy. In my experience, hierarchies like this come from two lines of design.
The Java/C# ideal of having everything derived from a common base class. This is a horrible idea in C++ and should never be used. Each object should derive from what it needs to, and only that. C++ was built on the "pay for what you use" principle, and deriving from a common base works against that. In general, anything you could do with such a common base class is either something you shouldn't be doing period, or something that could be done with function overloading (using operator<< to convert to strings, for example).
Misuse of inheritance. Using inheritance when you should be using containment. Inheritance creates an "is a" relationship between objects. More often than not, "has a" relationships (one object having another as a member) are far more useful and flexible. They make it easier to hide data, and you don't allow the user to pretend one class is another.
Make sure that your design does not fall afoul of one of these principles.
There will be but not as bad as the programmer performance implications.
As #Nicol points out, it may be doing a number of things.
If those are things that you require to be done, regardless of design, because they are all precisely necessary steps in getting the program from call main to exit within the fewest possible cycles, then your design is simply a matter of coding clarity (or maybe lack of it :).
In my experience performance tuning, as in this example, what I often see as a huge source of wasted time is over-design of data (i.e. class) structures.
Wierdly enough, the justification for the data structures is often (guess what?) - performance!
In my experience, the thing to do with data structure is keep it as simple as possible and as normalized as possible. If it is completely normalized, then any single change to it can't make it inconsistent. You can't always achieve complete normality, in which case you have to deal with the possibility that the data can be temporarily inconsistent.
This is why people write notification handlers, and this is encouraged in OOP.
The idea is, if you change something in one place, that can trigger notifications that "automatically" propagate the change to other places, trying to maintain consistency.
The problem with notifications is they can run away. Simply changing some boolean property from true to false can cause a fire-storm of notifications ripping through the data structure in ways no one programmer understands, updating databases, painting windows, zipping files, etc. etc. I often find this is where most clock cycles go.
I think it is simpler and far more efficient to temporarily tolerate inconsistency, and periodically repair it with some kind of sweeping process.
Another way data structures go along with huge inefficiency is if the data is effectively being interpreted by some process to produce some output.
This is very common in graphics.
If the data changes at a very slow rate, it may make sense to "compile" it rather than "interpret" it.
In other words, translate it into a simpler instruction set, or source code which is compiled "on the fly", which can then execute far more quickly to produce the desired output.
This applies to several cases in my application:
I have 3 or 4 functions that belong together, one is a starting function that creates and frees the required memory structures and calls the other functions as appropriate. The other functions also call themselves repeatedly. Only the starting functions is called from outside, and only once or not at all per application-run.
Currently, I pass pointers to the memory structures from the starting function as function arguments, but the argument list is getting quite long in some cases.
Is there any argument against creating classes for all these cases and making the pointers to the memory structures members?
Definitely go for a class here. That's what objects and classes are designed for.
It seems to be a quite typical use case for classes: Just add the "memory structure" as protected member of the class and initiliaze it in the constructor.
The member functions (aka "method") than can work on the data.
If you have different, but similiar use cases, you may also make use of subclassing, so you create a base class with default implementation and create some derived class that overwrites some of the methods with an own implementation.
But note, that you could also use other members varibales to set the behaviour at runtime (e.g. a bool that is used to toggle on or off a specific behaviour).
Your question is too abstract to see what is the best solution for your case. Remember, often there are a lot of solutions - and so there is more than one good solution.
It sounds to me like these functions belong in a class - with the internal functions private or protected - likewise with the members.
Yes, relate them all within a class.
This will also give you a cleaner code which might help you minimize the functions' arguments lists.
In simple words an object can be anything you decide. Say a person. This is an object which I'll decide to define as a class if I'll write a program that needs to keep information regarding people.
There are much better explanations than this, just google/wikipedia it.
i'm just reading meyers "More Effective C++ 35 New Ways" - item 33, and he suggest there
always to inherit from an abstract base class, and not a concrete.
one of the reason he claims, which i can't quite get , is that with inheriting from an abstract class, treating array polymorphically (item 3 in the book) is not a problem.
can someone suggest how is that ?
In addition i would like to hear if it's really always a good thing never to let the client instantiate a class which other derives from ? (meyers in his book is showing a problem with the assignment operator for example )
code example as requested:
CLASS BST {.... };
CLASS BlanacedBST:: public BST {....}
void printBSTArray(ostream& s, const BST array[],int Numelements)
{
for(int i=0;i < Numelements;i++)
{
s << array[i];
}
}
BST BSTArray[10];
printBSTArray(BSTArray); // works fine
BlanacedBST bBSTArray[10];
printBSTArray(bBSTArray); // undefined behaviour (beacuse the subscript operator advances the pointer according to BST chunk size)
then, he addes that avoiding concreate class (BlanacedBST) inheriting from another concreat class(BST) usually avoids this problem - this i don't get how.
While I think that avoiding inheritance from non-abstract classes is a good design guideline and something that should make you think twice about your design, I definitely do not think that it's in the category of 'never do this'.
I will say that classes designed to be inherited from that have data in them should probably be hiding their assignment operator because of the slicing issue.
I think there's a way to categorize classes that isn't often thought of, and I think that causes a lot of confusion. I think there are classes that are designed to be used by value, and classes that are designed to always be used by reference (meaning via a reference or a pointer or something like that).
In most object oriented languages user defined classes can only be used by reference, and there are a special class of 'primitive' types that can be used by value. One of C++'s big strengths is that you can create user defined classes that can be used by value. This can lead to some huge efficiency wins. In Java, for example, all of your points (to pick a random simple class) are heap allocated and need to be garbage collected, even though they're basically just two or three doubles stuck together with some nice 'final' support functions.
So classes that are designed to be used by reference should disable assignment and should seriously consider disabling copy construction and require people to use a 'make a copy of this' virtual function for that purpose. Notice that Java classes generally don't have anything like an assignment operator or standard copy constructor.
Classes that are designed to be used by value should generally not have virtual functions, though it may be very useful to have them be a part of an inheritance hierarchy. They can still be rather complex though because they can contain references to objects of classes designed to be used by reference.
If you need to treat a by reference class as being used by value you should use the handle/body design pattern or a smart pointer. The STL containers are all designed to be used on by value objects, so this is a fairly common problem.
Meyers does not say that you can create the array with no problems; he says that it will be more difficult for you to try to create it. The compiler will complain as soon as you try to initialise it, because you cannot create objects of the base class if it is abstract.
I have a class with a lot of built-in type members with read/write access. Should I make them public members and provide get/set methods for each one? How about structures?
The whole reason to have accessors (getters) and modifiers (setters) is to provide yourself with an extra level of indirection.
This extra level of indirection allows you to provide a read only view of your variable to a public interface, while not allowing your data member to be changed. You could still use a private or protected setter.
Setters allow you to do special error checking, validation and corrections when a value is set. For example setDirectory(const std::string &strPath), you could make sure there is a terminating slash if the user didn't specify one. This ensures that your class state will always be valid.
Getters can also shield your members from having them exposed to allow pointers to them. By not allowing pointers to them from the outside, you can ensure that if your object goes out of scope it won't lead to a crash.
The extra level of indirection for getters/setters also allow you to be able to change the data member that they encapsulate.
With a getter you can also obtain different views of your data, example: getMinutes, when your data member is actually stored in seconds.
This is not the reason to use them, but a nice side effect of using getters and setters is that you can set a breakpoint inside your modifier for example to see exactly when it is changed.
Whether you should use them or not is a judgement call based on your need. If you have so many members that it is a huge pain to provide getters and settings you could consider storing the data members in a struct and using that struct inside your class instead. You could even provide getters/setters for an object for the whole struct at once.
If there are invariants you need to preserve, then yes. Otherwise, don't bother.
Firstly, if your class has a lot of data mamebers it is probably not well designed. You may need to consider splitting it into multiple classes or storing the data in structures such as maps.
As regards providing accessors, the question is will you ever want to modify the access, possibly preventing it. If the answer is yes, then you need access functions. On the other hand, if your class is really just a bag of bits, with no behaviour, then make it a structure.
You should use public data members only
in structures, that you don't expose to client code (eg. bind-style functors) - it's useless to protect structures that noone outside will ever get
if their types encapsulate the logic of set/getting them (eg. if you create a class ObservableAttribute)
if they are const-members in an immutable structure (you can't do much except to read them if they're immutable)
If you create a public data member, you have to be sure that its value is fully orthogonal with other members of the class. Eg., you disable future possibilities of
observing changes to the member
making the member play any part in the class' invariant
disabling access to the member
changing the implementation of the member (eg. computed vs. cached vs. stored) if performance needs it
Using get/set methods for private/protected data members is a bad design.
It causes client code to be dependent on the implementation details of your class.
Changes in your class causes changes in client code.
However get/set methods for public members can be used. But it is always good to avoid them.