I need a template class, which has different members, depending on which ctor is called.
I managed to get a class, which has different members using sfinae with a base class (I did it almost like this SFINAE on member variable).
Now my question is, can I achieve a single template class, which has different members, depending on which ctor of the class is called?
Maybe someone can has an idea how to achieve this.
EDIT: I currently use boost::variant, but the problem is, that the largest object in the variant is huge, and the the smallest is ust a pointer. this is a real performance problem, because most of the time the pointer will be in the variant.
EDIT II: If this would work with a ctor it would be awesome, but if not, a factory-fuction would work as well.
EDIT III (or what I am trying to achieve):
I am currently making a DSL, which translates to C++.
Since I am trying to make polymorphism possible, I am only passing pointers to functions. Beacause some pointers are reference counted and some pointers are raw, depending on what the user wants, there can be shared_pointers and raw pointers of the same class. Thats why I can't make two different classes, because if a function is called on a pointer, it should be the same function, otherwise I have to overload all the fnctions, which would give me
2**n functions when the function has n arguments.
Thats why I am trying to create a class, which could eigther represents a raw pointer or a shared_ptr, based on what is passed to the ctor.
You should simply continue using variant<> but instead of storing your huge class as an object, store it as a pointer as well:
boost::variant<common_case*, huge_class*>
Since you say you usually store a pointer anyway, this doesn't cost you anything, and reclaims 100% of the wasted memory because all object pointers are the same size.
Related
I'm implementing a "variant" class which must have the smallest possible memory footprint and store some objects with a shared pointer mechanism.
For this, I would like to make a union within the class of all variable types. This includes some shared_ptr's.
The operator= and copy constructors must change the data type of the variant, hence switching to another member in the union. Upon switching to a shared_ptr, this one should be reset to null without deleting/deowning the pointer. Is there a way to do this?
Of course, there would be other ways to implement this but they are generally more complex, less safe or more memory consuming in my case. Any suggestion welcome though.
Thanks!
Resetting to null isn't sufficient; the implementations of
std::shared_ptr I know also have a pointer to the reference
count, which must be deleted as well.
You need to keep track of what is currently in the union, and
use explicit calls to the destructor and placement new for
construction any time the type changes (and in the constructors
and the destructor).
I have a problem which I cannot understand:
Let's Say I have a class System with several member fields, and one of them is of type unordered_map, so when I declare the class in the header file, I write at the beginning of the header #include <unordered_map>.
Now, I have two ways of declaring this field:
1.std::unordered_map<std::string,int> umap;
2.std::unordered_map<std::string,int>* p_umap;
Now in the constructor of the class, if I choose the first option, there is no need to initialize that field in the initializer list since the constructor of class System will call the default constructor for the field umap as part of constructing an instance of type class System.
If I choose the second option, I should initialize the field p_umap in the constructor (in the initialize list) with the operator new and in the destructor, to delete this dynamic allocation.
What is the difference between these two options? If you have a class that one of it's fields is of type unordered_map, how do you declare this field? As a pointer or as a variable of type unordered_map?
In a situation like the one you are describing, it seems like the first option is preferable. Most likely, in fact, the unordered map is intended to be owned by the class it is a data member of. In other words, its lifetime should not be extended beyond the lifetime of the encapsulating class, and the encapsulating class has the responsibility of creating and destroying the unordered map.
While with option 1 all this work is done automatically, with option 2 you would have to take care of it manually (and take care of correct copy-construction, copy-assignment, exception-safety, lack of memory leaks, and so on). Surely you could use smart pointers (e.g. std::unique_ptr<>) to encapsulate this responsibility into a wrapper that would take care of deleting the wrapped object when the smart pointer itself goes out of scope (this idiom is called RAII, which is an acronym for Resource Acquisition Is Initialization).
However, it seems to me like you do not really need a pointer at all here. You have an object whose lifetime is completely bounded by the lifetime of the class that contains it. In these situations, you should just not use pointers and prefer declaring the variable as:
std::unordered_map<std::string, int> umap;
Make it not a pointer until you need to make it a pointer.
Pointers are rife with user error.
For example, you forgot to mention that your class System would also need to implement
System( const Sysytem& )
and
System& operator= ( const System& )
or Bad Behavior will arise when you try to copy your object.
The difference is in how you want to be able to access umap. Pointers can allow for a bit more flexibility, but they obviously add complexity in terms of allocation (stack vs heap, destructors and such). If you use a pointer to umap, you can do some pretty convoluted stuff such as making two System's with the same umap. In the end though, go with KISS unless there's a compelling reason not to.
There is no need to define it as pointer. If you do it, you must also make sure to implement copy constructor and assignment operator, or disable them completely.
If there is no specific reason to make it a pointer (and you don't show any) just make it a normal member variable.
When should I define a type as a struct or as a class?
I know that struct are value types while classes are reference types. So I wonder, for example, should I define a stack as a struct or a class?
Reason #1 to choose struct vs class: classes have inheritance, structs do not. If you need polymorphism, you must use classes.
Reason #2: structs are normally value types (though you can make them reference types if you work at it). Classes are always reference types. So, if you want a value type, choose a struct. If you want a reference type, it's easiest to go with a class.
Reason #3: If you have a type with a lot of data members, then you're probably going to want a reference type (to avoid expensive copying), in which case, you're probably going to choose a class.
Reason #4: If you want deterministic destruction of your type, then it's going to need to be a struct on the stack. Nothing on the GC heap has deterministic destruction, and the destructiors/finalizers of stuff on the GC heap may never be run. If they're collected by the GC, then their finalizers will be run, but otherwise, they won't. So, if you want your type to automatically be destroyed when it leaves scope, you need to use a struct and put it on the stack.
As for your particular case, containers should normally be reference types (copying all of their elements every time that you pass one around would be insanely expensive), and a Stack is a container, so you're going to want to use a class unless you want to go to the trouble of making it a ref-counted struct, which is decidedly more work. It just has the advantage of guaranteeing that its destructor will run when it's not used anymore.
On a side note, if you create a container which is a class, you're probably going to want to make it final so that its various functions can be inlined (and won't be virtual if that class doesn't derive from anything other than Object and they're not functions that Object has), which can be important for something like a container where performance can definitely matter.
Read "D"iving Into the D Programming Language
In D you get structs and then you get classes. They share many amenities but have different charters: structs are value types, whereas classes are meant for dynamic polymorphism and are accessed solely by reference. That way confusions, slicing-related bugs, and comments à la // No! Do NOT inherit! do not exist. When you design a type, you decide upfront whether it'll be a monomorphic value or a polymorphic reference. C++ famously allows defining ambiguous-gender types, but their use is rare, error-prone, and objectionable enough to warrant simply avoiding them by design.
For your Stack type, you are probably best off defining an interface first and then implementations thereof (using class) so that you don't tie-in a particular implementation of your Stack type to its interface.
I'm writing a delegate class for educational purposes and have run into a little problem. The delegate must be able to call not only functions but also member methods of objects, which means that I need to store a pointer to a method:
void (classname::*methodPtr)(...);
And I need to store pointers to methods from different classes and with different argument lists. At first I just wanted to cast the method pointer to void *, but the compiler dies with an invalid cast error. Turns out that sizeof(methodPtr) == 8 (32-bit system here), but casts to unsigned long long also fail (same compiler error - invalid cast). How do I store the method pointer universally then?
I know it's not safe - I have other safety mechanisms, please just concentrate on my question.
You don't. You use run-time inheritance, if you need abstraction, and create a derived class which is templated on the necessities, or preferably, just create a plain old functor via the use of a function. Check out boost::bind and boost::function (both in the Standard for C++0x) as to how it should be done- if you can read them past all the macro mess, anyway.
You better listen to DeadMG. The problem is, that the size of a member pointer depends on the class type for which you want to form the member pointer. This is so, because depending on the kind of class layout (for example if the class have virtual bases and so on) the member pointer has to contain various offset adjustment values - there is no "one size fits all" member pointer type you can count on. It also means, that you can not assume to have a "castable" integral type which can hold every possible member function pointer.
I was wondering if there is a way in C++ to accomplish the following:
I have a base class called ResultBase and two class that are Derived from it, Variable and Expression. I have a few methods that do work on vector<ResultBase> . I want to be able to pass in vectors of Variable and Expression into these methods. I can achieve this by creating a vector<ResultBase> and using static_cast to fill it with the members from my vector of Variable/Expression. However, once the vector has run through the methods, I want to be able to get it back as the vector of Result/Expression. I'll know for sure which one I want back. static_cast won't work here as there isn't a method to reconstruct a Variable/Expression from a ResultBase, and more importantly I wouldn't have the original properties of the Variables/Expressions
The methods modify some of the properties of the ResultBase and I need those changes to be reflected in the original vectors. (i.e. ResultBase has a property called IsLive, and one of the methods will modify this property. I want this IsLive value to be reflected in the derived class used to create the ResultBase
Whats the easiest way to accomplish this?
vector<ResultBase *> should fix your slicing problem - a vector<ResultBase> will never contain classes derived from ResultBase, but rather copies that "slice off" e.g. Expression by copying the ResultBase part of it.
See What is object slicing? for a detailed explanation of slicing.
One possibility is to change your functions that do work on vector<ResultBase> into function templates that do work on vector<T>, with T a template parameter. To be even more generic, perhaps the functions can operate on a pair of iterators instead of a particular container type.
You can then call them with a vector<Variable> or vector<Expression> instead of a vector<ResultBase>, as long as Variable and Expression are both proper substitutes for ResultBase, as a derived class should be.
Alternatively as Erik says you can use pointers to get polymorphic behavior with containers. For ease of memory management, a vector of smart pointers or a Boost ptr_vector is usually preferred to a vector of raw pointers.
There's no way to convert an instance of a derived class to base and then back to derived, while preserving its original value, for pretty much the same reason that it's not possible to convert from int to char and then back, preserving the original value. If all else fails, you could perhaps bodge something together where you use the modified ResultBase objects to somehow update the original Variable or Expression objects with any changes made by the functions.