I'm looking to do simulations with very complicated initial conditions from the user. I'm writing class A whose member variables need to be initialized by the user before running A.Solve() to get the results stored in a file. The initialization is rather complicated and requires several temporary data structures that will no longer be needed after the initialization. So, I wrote another class called class Initializer which stores a reference to an object of class A. My code will look like this:
class A {
friend class Initializer;
private:
// member variables storing the state of the system
public:
void Solve();
...
};
class Initializer {
private:
A& a
// Other data structures used in the initialization
...
public:
// functions called by the user to set up for the initialization
...
Initialize(); // after this is called, a will be ready to solve
};
int main(...) {
A a;
Initializer init(a);
// call functions on init to initialize the system
...
init.Initialize();
a.Solve();
return 0;
}
But it seems like data structures in init will live on the stack for the entire program. To prevent that, is it ok to do this:
A a;
Initializer *init = new Initializer(a);
....
init.Initialize();
delete init;
a.Solve();
Or does this look unnecessary and should I just have everything contained in class A?
To answer your original line of thought, the usual solution is to restrict the scope of the init variable:
A a;
{
Initializer init(a);
//...
} // init is destroyed as soon as the scope exits
a.Solve();
Your new/delete variant is quite brittle and will leak memory if anything throws between new and delete. To fix that, use smart pointers:
A a;
std::unique_ptr<Initializer> init(new Initializer(a));
//...
init.reset();
a.Solve();
However as others have said, this whole design is kinda weird and probably overkill. If the initialization is really so complicated that you can't get away with constructors then you may want to do it the other way around: instead of Initializer taking an argument A and operating on it, you should pass a fully ready-to-use Initializer to A's constructor, which will in turn either copy the whole Initializer to keep a copy of the data, or just copy the relevant bits. Initializer should then probably be renamed to Config or something like that. Notice how a Config/Initializer object can now be reused to initialize several A objects, and even be modified between two A initializations.
Unfortunately this is hard to give you definitive advice with so little information.
Note: if you use C++11 you may be interested in std::initializer_list which enables the new brace-initialization syntax. Depending on the complexity of your data it may involve more work than your current solution but you'll end up with a very nice and intuitive syntax.
Here, using another class for initialization purpose seem to be overkill.
Just initialize in class A constructor.
Once the constructor execution completes, the temporary data structures will be freed automatically.
Related
I'm trying to understand how to model ownership properly in C++, and I'm having trouble precisely understanding who owns what when.
For example I had a class like this, with a very complex init list and complex members who also have complex init lists.
class ComplexClass {
public:
OtherComplexClass1 foo1;
OtherComplexClass2 foo2;
//...
OtherComplexClassN fooN;
ComplexClass(
int arg1, int arg2, int arg3) :
foo1(OtherComplexClass1{arg1,arg2}),
foo2(OtherComplexClass2{arg3}),
//...
fooN(OtherComplexClassN{foo1,foo2,foo3,foo4})
{};
};
Using this I was able to allocate like so
auto my_class = ComplexClass(1,2,3);
and use the class fine. However now I want to make a dynamic number of these so I tried this
auto my_vec = std::vector<ComplexClass>{};
my_vec.emplace_back(ComplexClass{1,2,3});
But doing this I had a lot of memory errors. When I instead do
auto my_vec = std::vector<std::unique_ptr<ComplexClass>>{};
my_vec.emplace_back(std::make_unique<ComplexClass>(1,2,3));
everything seems to be working. My question is, why does the second way work and not the first?
Thank you
EDIT:
Added more precise description of error(s)
Added more precise example of object structure
(1) I actually have two scenarios. One is the one I described
auto my_vec = std::vector<ComplexClass>{};
my_vec.emplace_back(ComplexClass{1,2,3});
with the code in a free function (catch2 test).
The other is where I actually have the above, but inside the constructor of a holding class.
In the first case I get
==60617==ERROR: AddressSanitizer: heap-use-after-free
indicating a member function of one of the complex classes. In the second case I get ==60565==ERROR: AddressSanitizer: heap-use-after-free indicating a std::dequeue member of one of the complex classes.
(2) The ComplexClass and OtherComplexClassK tree goes a few levels deep, and many members somewhere in the tree are references to other members in the tree. Maybe that's causing the problem? I have made sure that all references are references to a member that is ultimately constructed in an init list.
The remarks so far have been very helpful.
Your class should be default-constructible, copy-assignable and copy-constructible. See this answer: https://stackoverflow.com/a/33110129/5132939 for more details. Also it's desired to make it move-constuctible and move-assignable. In some cases std::vector will use move semantics instead of copy.
Aggregate initialisation does not comply with user-declared constructors.
I believe this is a common problem, but some googling does not return match, hence ask here.
So I have the following class:
class A {
public:
A(const A &rhs) { m_a = rhs.m_a; }
private:
int m_a;
};
Everything is cool until some time later, could be a year later, I add a new property, m_b to class A, but I forget to update the copy constructor.
It takes a painful debug to locate the out-of-sync.
Is there a trick to avoid such a problem, ideally at build time?
Yes, I can write unit test to cover that copy constructor, but when I forget updating copy constructor, most likely I forget that unit test also.
Turn on all your compiler warnings. You should hopefully get a warning about any uninitialized member variables. On GCC the specific flag for this is -Weffc++. See this StackOverflow post for more info.
Also, assign your values in the initializer list and not the constructor body whenever possible.
The best approach is probably to rely on the default copy constructor. For instance, your particular example, which involves a member-wise copy, works fine with the default constructor (i.e., the behavior would be the same even if you simply deleted the constructor). As more members are added, they will automatically receive the same member-wise copy behavior in the default constructor.
In some unusual cases you might want to force the generation of the default constructor (e.g., when you want to have some different, explicitly defined behavior for non-const source objects). In that case, in C++11 and later, you can explicitly request the default copy constructor as follows:
A(const A&) = default;
Some coding guidelines also recommend always including the above explicit request for the default constructor simply as a form of documentation.
Mostly member-wise, with exceptions
Sometimes, most member of a class are fine with the default member-wise copy, but you have a couple of exceptions. An example would be a raw pointer where you want to perform a deep copy of the underlying data. By default, the pointer is simply copied and so the pointers in the source object and new object will both point to the same location in memory.
The solution is fairly simple: just wrap this pointer and any associated meta-data (e.g., a length field if the pointed to object is an array) in a suitable RAII wrapper whose copy constructor performs the specific non-default behavior you want, and include a member of this type in your class A. Now A can continue to use the default copy constructor, which calls your explicit copy constructor for your pointer. Essentially, you are back to the pure member-wise copy, but with the new semantics for your pointer-wrapping member.
This type of matter will also help you keep your destructor and sometimes your constructors trivial as well. No doubt the original class above had some code to delete your raw pointer. Once wrapped with the copying-RAII wrapper, the wrapper takes care of destruction and so the containing class doesn't have to, and often the destructor can be removed entirely.
This wrapper approach often has zero or close to zero overhead in a language like C++.
You can find some more details in this question.
When that doesn't work
Sometimes the above may not work. One example would be when the copy constructor needs to embed the address (the this pointer) of the new object in some field. The self-contained wrapper doesn't have a way to get the this pointer of the containing object (indeed, it doesn't even know it is a member).
One approach here is to create a new sub-object with all of the fields of your original object that use the default copy behavior, and then create your new top level object by aggregating (or by inheritance) this sub-object with the few fields that do need special treatment. Then you can keep the using the default copy constructor for all the fields that should have the default treatment.
This approach can even have performance benefits, since compilers are likely to use a pure memcpy approach1 for the sub-object, in addition to calling your explicit code for the exceptional fields. When the fields were mingled together in the original object, this is much less likely or impossible (e.g., because the layout of the object may interleave the exceptional fields and default-copied fields).
1 This doesn't actually mean that there will be a call to the standard library memcpy in the code: for small objects the compiler will usually unroll this for small objects into an unrolled sequence of mostly maximum width loads and stores.
The only time you ever need to write copy constructors, assignment operators or destructors is if your class is an RAII wrapper for exactly one resource.
If your class is managing more than one resource, it's time to refactor it so that it's composed of classes which manage exactly one resource.
example:
#include <algorithm>
// this class is managing two resources.
// This will be a maintenance nightmare and will required
// horribly complicated constructor code.
struct DoubleVector
{
int *vec1;
int *vec2;
};
// this class manages a single resource
struct SingleVector
{
SingleVector() : vec (new int[10]) {}
SingleVector(SingleVector const& other)
: vec (new int[10])
{
// note - simple constructor
std::copy(other.vec, other.vec + 10, vec);
}
SingleVector& operator=(SingleVector const& other)
{
auto temp = other;
std::swap(vec, temp.vec);
return *this;
}
~SingleVector() {
delete [] vec;
}
// note - single resource
int *vec;
};
// this class uses *composition* and default assignment/construction/destruction
// it will never go wrong. And it could not be simpler.
struct DoubleVectorDoneRight
{
SingleVector vec1;
SingleVector vec2;
};
int main()
{
SingleVector v;
SingleVector v2 = v;
SingleVector v3;
v3 = v;
}
Well, I'm gonna be pretty straightforward here, I just have a piece of code in c++ which I'm not sure I really understand and need some help with.
Ok, to simplify lets just say I have a class that is defined like this: (the real class is a little bit more complicated, but this is what matters)
class myClass : public Runnable {
Semaphore *m_pMySemaphore;
__Queue<Requests> *m_pQueue;
Request m_Request;
VetorSlotBuffer *m_vetorSlotBuffer;
}
Up to here nothing is wrong, myClass is just a regular class which has 3 members that actually are pointers to other classes and an object of the class Request, the implementation of those classes not being important for my point here.
Then when this person implemented the constructor for myClass he or she did this:
myClass::myClass() : m_pMySemaphore(0), m_pQueue(0), m_vetorSlotBuffer(0) {
}
It's pretty evident that those three variables are treated like that by the constructor because they are pointers, am I right? but what kind of syntax is that? am I setting the pointers to null by doing that? I've seen a little bit of c++ already but never found something like that.
And secondly, what's the deal with the ":" after the constructor declaration? that I've seen but never took the time to investigate. Is this like an inner class or something?
Thank you very much in advance.
Nelson R. Perez
This is an initialization list
And it's the recommended way to initialize your members
It's member's initialization on object creation, called initialization list.
You can't initialize them elsewhere, say:
class X {
int i = 0; // error bad syntax
}
Neither in constructor by use of assignment, if they're const :
class X {
const int i;
X(){
i = 0; // error it's a const
}
}
So the c++ guys made up that syntax!
Yes, those pointers are being initialized to NULL. The key thing here is that they are initialized, as opposed to assigned. I.e.:
myClass::myClass()
: m_pMySemaphore(0), // initialized to 0
m_pQueue(NULL) // initialized to NULL (preferable to 0)
// no initializer for m_Request - uses default constructor
// no initializer for m_vectorSlotBuffer
{
// at this point, the object is entirely initialized, and can be used.
// this next line ASSIGNS to the member
m_vectorSlotBuffer = 0;
}
What happens to m_vectorSlotBuffer, is that it is initialized, and then assigned, in two separate steps. By doing it like m_pQueue, we save a step, and initialize properly. This becomes very important when we want to use non-default constructor, or if we want to initialize const members.
Also, the : after the constructor () is what begins the initialization section, before we get to the { where we enter the body of the constructor.
Finally, NULL is not guaranteed to be 0. NULL is portable, but most architectures use 0 as NULL.
EDIT: 0/NULL distinction is not meaningful anymore. Just pick one and be consistent.
Yes, pointers set to 0 are pointers set to null.
The : syntax for constructors is called initialization lists. It's used here for initializing member fields in a simple, direct manner. Should be easy to google with the proper terminology.
is it possible to re-initialize an object of a class using its constructor?
Sort of. Given a class A:
A a;
...
a = A();
the last statement is not initialisation, it is assignment, but it probably does what you want.
Literally? Yes, by using placement new. But first you have to destruct the previously constructed object.
SomeClass object(1, 2, 3);
...
object.~SomeClass(); // destruct
new(&object) SomeClass(4, 5, 6); // reconstruct
...
// Final destruction will be done implicitly
The value of this does not go beyond purely theoretical though. Don't do it in practice. The whole thing is ugly beyond description.
It's possible, although it's a very bad idea. The reason why is that without calling the destructors on the existing object, you are going to leak resources.
With that major caveat, if you insist on doing it, you can use placement new.
// Construct the class
CLASS cl(args);
// And reconstruct it...
new (&cl) CLASS(args);
In C++11, you can do this:
#include <type_traits>
template <class T, typename... Args>
void Reconstruct(T& x, Args&&... args)
{
static_assert(!std::has_virtual_destructor<T>::value, "Unsafe");
x.~T();
new (&x) T(std::forward<Args>(args)...);
}
This allows you to use Reconstruct passing arbitrary constructor parameters to any object. This can avoid having to maintain a bunch of Clear methods, and bugs that can easily go unnoticed if at some point the object changes, and the Clear method no longer matches the constructor.
The above will work fine in most contexts, but fail horribly if the reference is to a base within a derived object that has a virtual destructor. For this reason, the above implementation prevents use with objects that have a virtual destructor.
Short answer:
No. If part of your object's intended behavior is to be initialized several times, then the best way to implement this is through an accessible initialization method. The constructor of your class can simply defer to this method.
class C1 {
public:
C1(int p1, int p2) {
Init(p1,p2);
}
void Init(int p1, int p2) { ... }
};
Nitpicker corner:
Is there some incredibly evil way to call a constructor in C++ after an object is created? Almost certainly, this is C++ after all. But it's fundamentally evil and it's behavior is almost certainly not defined by the standard and should be avoided.
No, constructors are only called when the object is first created. Write a new method to do it instead.
Edit
I will not acknowledge placement new, because I don't want to have to get a pet raptor for work.
See this comic, but think of the topic on hand...
Yes you can cheat and use placement new.
Note: I do not advice this:
#include <new>
reInitAnA(A& value)
{
value.~A(); // destroy the old one first.
new (&value) A(); // Call the constructor
// uses placement new to construct the new object
// in the old values location.
}
I usually write the following in modern C++ :
SomeClass a;
...
a = decltype(a)();
It may be not the most effective way, as it effectively constructs another object of the same type of a and assigns it to a, but it works in most cases, you don't have to remember the type of a, and it adapts if the type changes.
Instead of destructing and reinitializing as suggested by some of the answers above, it's better to do an assignment like below. The code below is exception safe.
T& reinitialize(int x, int y)
{
T other(x, y);
Swap(other); // this can't throw.
return *this;
}
May-be not what you have in mind, but since you didn't mention what it is for, I suppose one answer would be that you'd do it by controlling scope and program flow.
For example, you wouldn't write a game like this:
initialize player
code for level 1
...
reinitialize player
code for level 2
...
etc
Instead you'd strive for:
void play_level(level_number, level_data) {
Player player; //gets "re-initialized" at the beginning of each level using constructor
//code for level
}
void game() {
level_number = 1;
while (some_condition) {
play_level(level_number, level_data);
++level_number;
}
}
(Very rough outline to convey the idea, not meant to be remotely compilable.)
If you really must do this I strongly encourage creating a reset method for this:
class A
{
...
public:
reset() { *this= A() };
}
The above requires A to be copy and move assignable.
That is because the initial unoptimized version will copy from a temp. However copy elision may remove this step.
The behavior of A::reset() is always well defined. It replace the existing data in a valid A instance with a data from a new one. Of course any sub-class of A will still need to define its own version if you wanted its data re-initialized as well. However, failure to do so does not in and of itself invoke undefined or unspecified behavior. It simply means that only whatever memory A uses for its members will be reset. Even the involvement of virtual functions and/or virtual inheritance doesn't change this. Although the usual caveats of using such things apply.
Raw pointers will not be deleted by the above so they will need to be put into a std::shared_ptr or similar construct so the will self destruct when no longer needed.
While most answers are reinitializing an object in two steps; first, creating an initial object, and second creating another object and swapping it with the first one using placement new, this answer covers the case that you first create a pointer to an empty object and later allocate and construct it:
class c *c_instance; // Pointer to class c
c_instance = new c(arg1, ..., argn) // Allocate memory & call the proper constructor
// Use the instance e.g. c->data
delete c_instance; // Deallocate memory & call the destructor
Yes , it is possible.
If you create a method that returns a new object.
#include "iostream"
class a // initialize class
a getNewA(a object){// Create function to return new a object
a new_object(/*Enter parameters for constructor method*/);
return new_object;
}
What's a good existing class/design pattern for multi-stage construction/initialization of an object in C++?
I have a class with some data members which should be initialized in different points in the program's flow, so their initialization has to be delayed. For example one argument can be read from a file and another from the network.
Currently I am using boost::optional for the delayed construction of the data members, but it's bothering me that optional is semantically different than delay-constructed.
What I need reminds features of boost::bind and lambda partial function application, and using these libraries I can probably design multi-stage construction - but I prefer using existing, tested classes. (Or maybe there's another multi-stage construction pattern which I am not familiar with).
The key issue is whether or not you should distinguish completely populated objects from incompletely populated objects at the type level. If you decide not to make a distinction, then just use boost::optional or similar as you are doing: this makes it easy to get coding quickly. OTOH you can't get the compiler to enforce the requirement that a particular function requires a completely populated object; you need to perform run-time checking of fields each time.
Parameter-group Types
If you do distinguish completely populated objects from incompletely populated objects at the type level, you can enforce the requirement that a function be passed a complete object. To do this I would suggest creating a corresponding type XParams for each relevant type X. XParams has boost::optional members and setter functions for each parameter that can be set after initial construction. Then you can force X to have only one (non-copy) constructor, that takes an XParams as its sole argument and checks that each necessary parameter has been set inside that XParams object. (Not sure if this pattern has a name -- anybody like to edit this to fill us in?)
"Partial Object" Types
This works wonderfully if you don't really have to do anything with the object before it is completely populated (perhaps other than trivial stuff like get the field values back). If you do have to sometimes treat an incompletely populated X like a "full" X, you can instead make X derive from a type XPartial, which contains all the logic, plus protected virtual methods for performing precondition tests that test whether all necessary fields are populated. Then if X ensures that it can only ever be constructed in a completely-populated state, it can override those protected methods with trivial checks that always return true:
class XPartial {
optional<string> name_;
public:
void setName(string x) { name_.reset(x); } // Can add getters and/or ctors
string makeGreeting(string title) {
if (checkMakeGreeting_()) { // Is it safe?
return string("Hello, ") + title + " " + *name_;
} else {
throw domain_error("ZOINKS"); // Or similar
}
}
bool isComplete() const { return checkMakeGreeting_(); } // All tests here
protected:
virtual bool checkMakeGreeting_() const { return name_; } // Populated?
};
class X : public XPartial {
X(); // Forbid default-construction; or, you could supply a "full" ctor
public:
explicit X(XPartial const& x) : XPartial(x) { // Avoid implicit conversion
if (!x.isComplete()) throw domain_error("ZOINKS");
}
X& operator=(XPartial const& x) {
if (!x.isComplete()) throw domain_error("ZOINKS");
return static_cast<X&>(XPartial::operator=(x));
}
protected:
virtual bool checkMakeGreeting_() { return true; } // No checking needed!
};
Although it might seem the inheritance here is "back to front", doing it this way means that an X can safely be supplied anywhere an XPartial& is asked for, so this approach obeys the Liskov Substitution Principle. This means that a function can use a parameter type of X& to indicate it needs a complete X object, or XPartial& to indicate it can handle partially populated objects -- in which case either an XPartial object or a full X can be passed.
Originally I had isComplete() as protected, but found this didn't work since X's copy ctor and assignment operator must call this function on their XPartial& argument, and they don't have sufficient access. On reflection, it makes more sense to publically expose this functionality.
I must be missing something here - I do this kind of thing all the time. It's very common to have objects that are big and/or not needed by a class in all circumstances. So create them dynamically!
struct Big {
char a[1000000];
};
class A {
public:
A() : big(0) {}
~A() { delete big; }
void f() {
makebig();
big->a[42] = 66;
}
private:
Big * big;
void makebig() {
if ( ! big ) {
big = new Big;
}
}
};
I don't see the need for anything fancier than that, except that makebig() should probably be const (and maybe inline), and the Big pointer should probably be mutable. And of course A must be able to construct Big, which may in other cases mean caching the contained class's constructor parameters. You will also need to decide on a copying/assignment policy - I'd probably forbid both for this kind of class.
I don't know of any patterns to deal with this specific issue. It's a tricky design question, and one somewhat unique to languages like C++. Another issue is that the answer to this question is closely tied to your individual (or corporate) coding style.
I would use pointers for these members, and when they need to be constructed, allocate them at the same time. You can use auto_ptr for these, and check against NULL to see if they are initialized. (I think of pointers are a built-in "optional" type in C/C++/Java, there are other languages where NULL is not a valid pointer).
One issue as a matter of style is that you may be relying on your constructors to do too much work. When I'm coding OO, I have the constructors do just enough work to get the object in a consistent state. For example, if I have an Image class and I want to read from a file, I could do this:
image = new Image("unicorn.jpeg"); /* I'm not fond of this style */
or, I could do this:
image = new Image(); /* I like this better */
image->read("unicorn.jpeg");
It can get difficult to reason about how a C++ program works if the constructors have a lot of code in them, especially if you ask the question, "what happens if a constructor fails?" This is the main benefit of moving code out of the constructors.
I would have more to say, but I don't know what you're trying to do with delayed construction.
Edit: I remembered that there is a (somewhat perverse) way to call a constructor on an object at any arbitrary time. Here is an example:
class Counter {
public:
Counter(int &cref) : c(cref) { }
void incr(int x) { c += x; }
private:
int &c;
};
void dontTryThisAtHome() {
int i = 0, j = 0;
Counter c(i); // Call constructor first time on c
c.incr(5); // now i = 5
new(&c) Counter(j); // Call the constructor AGAIN on c
c.incr(3); // now j = 3
}
Note that doing something as reckless as this might earn you the scorn of your fellow programmers, unless you've got solid reasons for using this technique. This also doesn't delay the constructor, just lets you call it again later.
Using boost.optional looks like a good solution for some use cases. I haven't played much with it so I can't comment much. One thing I keep in mind when dealing with such functionality is whether I can use overloaded constructors instead of default and copy constructors.
When I need such functionality I would just use a pointer to the type of the necessary field like this:
public:
MyClass() : field_(0) { } // constructor, additional initializers and code omitted
~MyClass() {
if (field_)
delete field_; // free the constructed object only if initialized
}
...
private:
...
field_type* field_;
next, instead of using the pointer I would access the field through the following method:
private:
...
field_type& field() {
if (!field_)
field_ = new field_type(...);
return field_;
}
I have omitted const-access semantics
The easiest way I know is similar to the technique suggested by Dietrich Epp, except it allows you to truly delay the construction of an object until a moment of your choosing.
Basically: reserve the object using malloc instead of new (thereby bypassing the constructor), then call the overloaded new operator when you truly want to construct the object via placement new.
Example:
Object *x = (Object *) malloc(sizeof(Object));
//Use the object member items here. Be careful: no constructors have been called!
//This means you can assign values to ints, structs, etc... but nested objects can wreak havoc!
//Now we want to call the constructor of the object
new(x) Object(params);
//However, you must remember to also manually call the destructor!
x.~Object();
free(x);
//Note: if you're the malloc and new calls in your development stack
//store in the same heap, you can just call delete(x) instead of the
//destructor followed by free, but the above is the correct way of
//doing it
Personally, the only time I've ever used this syntax was when I had to use a custom C-based allocator for C++ objects. As Dietrich suggests, you should question whether you really, truly must delay the constructor call. The base constructor should perform the bare minimum to get your object into a serviceable state, whilst other overloaded constructors may perform more work as needed.
I don't know if there's a formal pattern for this. In places where I've seen it, we called it "lazy", "demand" or "on demand".