Initialize class pointer object with reference to another class object - c++

I know this is a general question in C++, and my knowledge of it is all that needs to be improved in order to understand it.
But my problem is not knowing how to ask the question, so I'm having trouble googling it.
I want to initialize a pointer object of a class with a reference to a different class' object.
Assume we have two classes: One, Two.
I wanna do the following:
Two objOfTwo = Two(2):
One* objPointer[2] = { &objOfTwo, &objOfTwo };
The code is merely an example of what I want to do, so ignore the fact it's the same object for both indexes.
My question is how do I go about making sure this class accepts this type of initialization? A special constructor?
Thank you.

Related

Change number of members depending on constructor called

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.

Should I store references in classes in c++? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
When I was learning C++, I was told that if you want to have multiple classes reference the same object, you should give both a pointer to the object. In Modern C++, I'd probably interpret this as the object being a unique_ptr and the classes holding non-owning-raw-pointers.
Recently, my mentor at work suggested that you should only use pointers when you plan on having the store point to a different object or null at some point. Instead, you should store references in classes.
Reference member variables are a thing I've actually never seen before, so I was looking for advice on what the concerns were... It makes sense... You're saying that this reference is assumed to never be null... I guess the concern would then be that you couldn't /check/ for null. It would have to be an invariant of your class...
How about how this applies to using the references for polymorphism?
Update:
The answer that I selected covers my questions pretty well, but I thought I'd clarify for future readers. What I was really looking for was an idea of the consequences of using a reference rather than a pointer as a class member. I realise that the way the question was phrased made it sound more like I was looking for opinions on the idea.
Should I store references in classes in c++?
yes, why not. This question is IMO 'primarily opinion-based', so my answer is based on my own experience.
I use member references when I dont need what pointers have to offer, this way I limit possiblity that my class will be wrongly used. This means among other possibility to bind new value, assign nullptr, you cant take pointer to reference, you cannot use reference arithmetics - those features are missing in references. You should also remember that reference is not an object type, this means among others that if you put a reference as struct member, then it is no longer POD - i.e. you cannot use memcpy on it.
You should also remember that for classes which have non static reference member, compiler will not generate implicit constuctors.
For me this means references as variable members are mostly usefull when class is some kind of wrapper, or a holder. Below is an example which also shows an alternative implementation using pointer member type. This alternative implementation gives you no additional benefit to the reference one, and only makes it possible to introduce Undefined Behaviour.
struct auto_set_false {
bool& var;
auto_set_false(bool& v) : var(v) {}
~auto_set_false() { var = false; }
};
struct auto_set_false_ptr {
bool* var;
auto_set_false_ptr(bool* v) : var(v) {}
~auto_set_false_ptr() { *var = false; }
};
int main()
{
// Here auto_set_false looks quite safe, asf instance will always be
// able to safely set nval to false. Its harder (but not imposible) to
// produce code that would cause Undefined Bahaviour.
bool nval = false;
auto_set_false asf(nval);
bool* nval2 = new bool(true);
auto_set_false_ptr asf2(nval2);
// lots of code etc. and somewhere in this code a statement like:
delete nval2;
// UB
}
It is generally not a good idea to store references in a class because the class cannot be default constructed, copy assigned, move assigned, and the member cannot be changed (the reference cannot be rebound).
That renders the class uncopieable. It therefore cannot be copied, moved or placed in most containers. The far more flexible and less surprising solution is to store a pointer or a std::refernce_wrapper.
IMO references works like pointers.
The only difference is in dynamic_cast: a failed cast produces a nullpointer with pointers, and results in a throw an exception with references.
References are far better than pointers because of one reason: you don't have to play with nulls.
A reference can't be null and it is a big value to not have to check for nulls.
The small difficulty is that you have to assign reference member in a constructor.
But you can definitely change it later to other non-null value pointing to an object of a class of the member or subclass of this class.
So it supports inheritance like pointers do.

Wrapped reference-counting, questions about move-semantics

I'm working on a class that acts as a scope helper for reference-counted objects. The interface should allow to use the class as follows:
{
Handle<String> s = Handle<String>::New("Hello, World!");
s = s->Concat(Handle<String>::New(" My name is Peter"));
}
while String is the class that contains the reference-count.
I am not very familar with move semantics and I was unable to find a concrete paper which sates the conditions that apply for move-semantics. Basically, what I am wondering about is:
Can this be an object that was already initialized in the move-constructor? Because if that is the case, i can't tell apart if the member in my Handle class that points to the String contains some garbage value or is actually pointing to a real String.
I guess it's possible using placement construction, but doing so is asking for trouble. I don't even know why I mentioned it. Short answer: No, it cannot. Move constructors only differ from other constructors in the type of values they accept.

how to properly initialize a class containing many data members?

Suppose a class contains around 10 data members then what would be the proper way to initialize an object of that particular class? Create a constructor with 10 parameters or just provide a default constructor then use setter member functions or something else?
Basically I want to know how it is done in actual real life code?
thanks.
In actual real life code, I would be very reticent to have a class with 10 parameters that need to be set.
But also in real life, I know that this happens much more often than I would like. So here is what I would do:
First, evaluate your design. Do you really need all that stuff?
Second, if you really do need all that stuff, or if there's no way out due to a legacy design, then I would require every parameter in the constructor, and make the default constructor private. Everything should be initialized in an initialization list.
Sometimes when the data members and the class methods are sufficiently decoupled I would prefer to move all the data members to their own struct, and then have a member of that struct in the class. Take that struct by const reference and assign it in the init list. Make the struct member const.
Another [design] problem is that if you use class with that many arguments as a base class and then add more arguments (due to a requirement, for example), you may well forget to initialize them. So, yeah, refactor.
Isn't this really an OOP and design question?
What is the object here? Are all 10 fields attributes of that object? Can some be further grouped under another class?
Do you always have all 10 pieces of data when you need to instantiate the class? You can make constructors for the pieces you have and/or do setters/getters.

C++ converting back and forth from derived and base classes

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.