C++: making custom class to work like both container and normal class? - c++

I want to have some myObject which will store a collection (vector-like) of SomeOtherObjects (so, being homogeneous, right?), which should be iterable and accessible via (myObject[i]).SomeOtherObjectField1 but also will have normal members like myObject.doStuff() and myObject.Stuff.
Is there any option to implement such class, or using private std::vector to keep the objects (which I'm trying to avoid - don't like private std:: containers) will be smarter?

Prefer composition over inheritance, if your goal is code reuse. (Inheritance should be used to enable polymorphism, which doesn't seem to be an issue in this case.)

That's looks like the composite design pattern. In short, you have to define the interface of your Object class and derive concrete classes, some being container for others. As said, the composition way is better, but using a common interface is the way to use a 'simple' Object or a 'composite' Object the same way.
my2c

I would use a private std::vector<> and an inline method to return a const reference to it.
Why don't you like member std containers?

Often the right approach to structure lies in clarifying the semantics. You need to ask questions like
"Is myObject a vector<>?". The answer is probably not. If you then follow the principle that a class does one thing (cohesion), then it follows that syntactic sugar around the vector<> is probably not that good.
It tends to follow that the vector<> is a private member. There is no problem with then returning a const reference to it. Returning a non-const reference would break encapulsation - might as well be public data.
If you wish to have:
(myObject[i]).SomeOtherObjectMethod1();
then that is easy enough to implement through operator[](unsigned index). I suspect if you do want that you are better off being consistent and treating myObject as a container in its own right. This means not providing the const ref accessor to the vector<> and implementing the specific accessor methods you really require. This will make client code much easier to understand.

Related

How to make a std::vector type-safe

I have an obect called an IndexSet, currently defined as a std::vector, that I want to define as a separate type.
I want to be able to interact with it just as though it were a vector, but I also want type protection so that I don't accidentally use a "normal" vector when I want to use an IndexSet.
I have been able to come up with three options for how to do this, none of which please me. I am hoping that there is a fourth that I am missing.
Option #1: typdef
typdef vector<int> IndexSet
This allows me to use an IndexSet exactly as I would a vector, but it gives me zero type protection. I am able to pass a vector into a function expecting an IndexSet with zero complaints.
Option #2: Public Wrapper Class
class IndexSet
{
public:
vector<int> indexes;
};
This will give me type protection, but it requires me to use a level of indirection interacting with it. Instead of saying
set.push_back(1);
I have to say
set.indexes.push_back(1);
Option #3: Private Wrapper Class
class IndexSet
{
public:
push_back....
operator[]...
etc...
private:
vector<int> indexes
};
This will give me both type protection and allow me to interact directly with the IndexSet as though it were a vector, but ONLY if I first create wrapper methods for every single method of std::vector that I want to use with my IndexSet.
Of course, what I'd really like to do is to just create a new class that inherits from vector but has zero implementation of its own, but I know that the standard library containers do not like to be inherited from.
Are there any other options that I'm missing?
Is there some functionality that differs between an IndexSet and a vector? Is there some difference in how these objects are used? If the answer is no, then why do you want to do this?
Your typedef does not suffice only if there is something intrinsically wrong with supplying a std::vector<int> to a functions that expects an IndexSet. That would suggest that an IndexSet does not satisfy an is-a relationship with respect to std::vector<int>. That in turn means that even if you could public inheritance, you shouldn't be doing so.
If the relationship is implemented-by rather than is-a, this suggests using either containment or private (and possibly protected) inheritance. This is much safer than public inheritance from a container class because programmers who use your class have to go out of their way to get a base class pointer. (The way to do it is to use a C-style cast. C-style casts can convert a derived type to a parent class even if the inheritance is not public.)
The advantage of using private inheritance in instead of containment in this case is that you can easily promote selected inherited member functions from private to protected via the using statement. You would have to write a bunch of wrapper functions if you used containment.
class IndexSet : private std::vector<int> {
public:
// Bunch of constructors, elided.
using std::vector<int>::push_back;
using std::vector<int>::operator[];
using std::vector<int>::cherry_picking_of_only_the_stuff_you_want;
};
Update
There are some non-member functions associated with std::vector, specifically comparison operators and std::swap. Making comparable versions for your IndexSet will require wrapper functions, but there aren't that many (six comparison operators plus std::swap), and you only need these if that functionality makes sense for this class.
Let's face it, one solution has all the advantages and just one disadvantage.
If you subclass std::vector, you just have to make sure you don't mix pointers to std::vector and your class, so nobody will delete a pointer to std::vector when it is actually of your subclass.
Whether this is feasible depends on your project. If this is an object that will be used by alot of people, in a public library, an OSS project etc, you might be safer wrapping it, else just subclass std::vector. You'll be fine.
Don't forget to add a comment at your class interface explaining the dangers. And you might be able do disable casting operators for extra safety (make your ctor explicit, ...).
This sounds like a job for....BOOST_STRONG_TYPEDEF. http://www.boost.org/doc/libs/1_54_0/boost/serialization/strong_typedef.hpp
BOOST_STRONG_TYPEDEF(std::vector<int>, IndexSet)

Class in a struct

I have two questions.
I know it is possible to declare class objects in structs. But is it ethical to do that from design point of view?
In my scenario I have a structure with a huge number of member elements and I want to include a class object too. Here I have another question. If I memset() the whole struct the class handle is also reset. So, I check the size of the rest of the struct without the class object and subtract it while I call memset(), to get rid of this problem. (Please note that I am using STL class 'queue' here. And I cannot use sizeof() operator on the object, since it is not overloaded.)
But is this totally an unacceptable way to do that? Can you suggest some solution to this problem?
struct = class (except for default visibility).
If you have a “huge number of members” you are probably doing something wrong, change your design, otherwise it becomes intractable.
It is absolutely fine to nest classes and / or structs, where it makes sense. For instance, it’s common to define nested classes for implementation details (so a linked_list class could have a node member class).
There’s no such thing as a “class object”, and it’s not clear what you mean by that.
Don’t use memset – you probably don’t need it, just use normal constructors and assignment.
And I cannot use sizeof() operator on the object
Wrong, you can use it.
The solution is to avoid memset with classes and structures, and use constructors. In C++11 you can use initialization lists too under various conditions.
There is no much functional difference between classes and structs in c++. Structs exisist in c++ only for backward compatibility with C. So it is ok to have a class objects in structs. However I generally prefer structs that have only member variables with getter and setter. I dont use any functions inside struct that manupulate the data. If i need that then i will use class.

How to refactor an existing class to become polymorphic?

I have a class that is used as a member in many places in my project.
Now, instead of this class I want to have a polymorphism, and the actual object will be created by some kind of factory.
I have to choose between:
Having to change all the places where I use the class - to call the factory and use a pointer instead of object directly.
Changing the class to be just a wrapper, that will call functions of a new polymorphic class I will create.
Which strategy should I better choose?
Change all the places where I use the class to call the factory and use a pointer instead of object directly.
That's best. It seems painful at first, but it's clean and more extensible than implementing a wrapper because you didn't feel like doing a search for new MyClass(.
Once you list all the place with the new, you'll see that it isn't really all that bad a job.
Chances are that even if you go with #2 and implement a base class wrapper, you will have to modify the client code anyway (different methods of construction through a factory, e.g., for a polymorphic base wrapper).
I'd go with #1 but not a regular pointer, but something like boost::shared_ptr or boost::scoped_ptr (depending on what you need).
The second option might allow you to take some liberties with the base wrapper interface, but I'd recommend against that: favor the commonly-accepted approaches when possible. If the base class wrapper provides additional facilities that boost::shared_ptr doesn't provide, e.g., it will be a foreign entity which introduces new concepts in the system and probably with little or no benefits to show for it.
In the best case scenario, your base class wrapper duplicates the interface of something common and familiar to most developers like boost::shared_ptr, in which case it's reinventing the wheel and you might as well have used boost::shared_ptr. In the worst case scenario, your wrapper class introduces an interface that's completely different and therefore introduces foreign code to the system that others will not immediately recognize.
No matter how good you are, other developers will have a much easier time trusting and working with a peer-reviewed, well-documented, thoroughly-tested library like boost than a handrolled solution by one engineer. If only for that reason, try to use the existing library solutions as much as possible and prefer those to, say, a custom base class wrapper.
Your idea of using a wrapper even has a name. It's the letter/envelope idiom, as described by Coplien (before they started to call these idioms "patterns").
Google finds you more explanations for it.
Contrary to the others I don't see anything wrong with using it. For the class' users, it's much easier to deal with something that behaves as simple as a value type. No hassle of having to use a factory or a factory method for creating objects, since the class' constructors are the factories - which is what constructors were invented for in the first place.
What could be wrong with that?

Structs vs classes in C++ [duplicate]

This question already has answers here:
Closed 14 years ago.
When should someone use structs instead of classes or vice versa in C++? I find myself using structs when a full-blown class managing some information seems like overkill but want to indicate the information being contained are all related. I was wondering what are some good guidelines to be able to tell when one is more appropriate than the other?
Edit:
Found these links while reading the material Stack Overflow indicated was related after the question was submitted:
When should you use a class vs a struct in C++?
What are the differences between struct and class in C++?
Technically, the only difference between the two is that structs are public: by default and classes are private:
Other than that, there is no technical difference.
struct vs class then becomes a purely expressive nuance of the language.
Usually, you avoid putting complicated methods in a struct, and most of the time structs data members will stay public. In a class you want to enforce strong encapsulation.
struct = data is public, with very simple helper methods
class = strongly encapsulated, data is modified / accessed only through methods
I use structs for simple containers of types that provide no constructors or operators.
Classes for everything else.
Use a struct when you simply need a "bucket of stuff" that doesn't have logical invariants that you need to keep. Use a class for anything else.
See also what the C++ FAQ says on the subject.
Use a class if you have methods, a struct if not.
A class should hide all its internals only exposing methods or properties. A struct tends to expose all its internals and has no accessor methods.
Where only one bit of code is accessing some (related) data, a struct may be perfectly reasonable. Where multiple bits of code need to modify the data or if it's anything slightly complicated, a class would be a better bet.
The difference between Classes and Structs are that structs are groups of variables and classes represent objects. Objects have attributes AND methods and be part of a hierarchy.
If you're using C++ to take advantage of the OO capabilities it's best to use classes / objects which are more natural.
I always use class, even for just containers, for consistency. Its purely a choice of style since the difference between the two is negligible.
If you need to control access to the data, you should use classes. If you don't care who is accessing what, and what they're storing in there, then a struct is probably more appropriate.
Also, a class is more appropriate if you need to do any checks on the integrity of the data itself.
See existing questions:
What are the differences between struct and class in C++
When should you use a class vs a struct in C++?
Personally, I use structs when all I need is a container for data (no member functions).
Otherwise, I use classes.
The only time I make an exception to that rule is if I need a simple functor: e.g.
struct compare { bool operator() { ... } };
sort(v.begin(), v.end(), compare());
The need for a public: label would just clutter up the code unnecessarity.
structs in C++ are classes with a default access method of public, so technically other than that default there is no difference and you can use both equivalently.
Yet there are some expectations and natural tendencies, in part because structs in C++ come from C.
My approach: If it has any private data, a constructor/destructor, or any complex member functions (which do more than just conversion upon set/get, etc.), use class.

Extending an existing class like a namespace (C++)?

I'm writing in second-person just because its easy, for you.
You are working with a game engine and really wish a particular engine class had a new method that does 'bla'. But you'd rather not spread your 'game' code into the 'engine' code.
So you could derive a new class from it with your one new method and put that code in your 'game' source directory, but maybe there's another option?
So this is probably completely illegal in the C++ language, but you thought at first, "perhaps I can add a new method to an existing class via my own header that includes the 'parent' header and some special syntax. This is possible when working with a namespace, for example..."
Assuming you can't declare methods of a class across multiple headers (and you are pretty darn sure you can't), what are the other options that support a clean divide between 'middleware/engine/library' and 'application', you wonder?
My only question to you is, "does your added functionality need to be a member function, or can it be a free function?" If what you want to do can be solved using the class's existing interface, then the only difference is the syntax, and you should use a free function (if you think that's "ugly", then... suck it up and move on, C++ wasn't designed for monkeypatching).
If you're trying to get at the internal guts of the class, it may be a sign that the original class is lacking in flexibility (it doesn't expose enough information for you to do what you want from the public interface). If that's the case, maybe the original class can be "completed", and you're back to putting a free function on top of it.
If absolutely none of that will work, and you just must have a member function (e.g. original class provided protected members you want to get at, and you don't have the freedom to modify the original interface)... only then resort to inheritance and member-function implementation.
For an in-depth discussion (and deconstruction of std::string'), check out this Guru of the Week "Monolith" class article.
Sounds like a 'acts upon' relationship, which would not fit in an inheritance (use sparingly!).
One option would be a composition utility class that acts upon a certain instance of the 'Engine' by being instantiated with a pointer to it.
Inheritance (as you pointed out), or
Use a function instead of a method, or
Alter the engine code itself, but isolate and manage the changes using a patch-manager like quilt or Mercurial/MQ
I don't see what's wrong with inheritance in this context though.
If the new method will be implemented using the existing public interface, then arguably it's more object oriented for it to be a separate function rather than a method. At least, Scott Meyers argues that it is.
Why? Because it gives better encapsulation. IIRC the argument goes that the class interface should define things that the object does. Helper-style functions are things that can be done with/to the object, not things that the object must do itself. So they don't belong in the class. If they are in the class, they can unnecessarily access private members and hence widen the hiding of that member and hence the number of lines of code that need to be touched if the private member changes in any way.
Of course if you want to access protected members then you must inherit. If your desired method requires per-instance state, but not access to protected members, then you can either inherit or composite according to taste - the former is usually more concise, but has certain disadvantages if the relationship isn't really "is a".
Sounds like you want Ruby mixins. Not sure there's anything close in C++. I think you have to do the inheritance.
Edit: You might be able to put a friend method in and use it like a mixin, but I think you'd start to break your encapsulation in a bad way.
You could do something COM-like, where the base class supports a QueryInterface() method which lets you ask for an interface that has that method on it. This is fairly trivial to implement in C++, you don't need COM per se.
You could also "pretend" to be a more dynamic language and have an array of callbacks as "methods" and gin up a way to call them using templates or macros and pushing 'this' onto the stack before the rest of the parameters. But it would be insane :)
Or Categories in Objective C.
There are conceptual approaches to extending class architectures (not single classes) in C++, but it's not a casual act, and requires planning ahead of time. Sorry.
Sounds like a classic inheritance problem to me. Except I would drop the code in an "Engine Enhancements" directory & include that concept in your architecture.