Algorithmic initialization of instance variables in C++ - c++

I have been using Java for a very long time and I have problem getting used to C++ programming styles.
How we can manage scenarios like below:
Instance variables are objects which cannot be created using default constructor. In java constructor parameters can be decided upon in higher level class constructor.
Instance variable is a reference type and we need to run a simple algorithm (condition, calculation,...) in the constructor and then create and assign an object to that reference.
There are possibly similar scenarios in which we need to initiate instance variables in places other than the constructor initialization list. I guess GCC would allow to do that (issues a warning), but VC++ does not seem to allow.
I guess most of these can be done using pointers but I am trying to avoid pointers as much as I can (to minimize run-time crash and also hard to debug problems).

Instance variables are objects which cannot be created using default constructor. In java constructor parameters can be decided upon in higher level class constructor.
class A {
public:
A(int n);
}
class B {
public:
B(int n) : a1(n), a2(n+1) {}
private:
A a1, a2;
}
Instance variable is a reference type and we need to run a simple algorithm (condition, calculation,...) in the constructor and then create and assign an object to that reference.
static int n = 1;
static int m = 2;
class A {
public:
A(bool useN) : ref(useN ? n : m) {}
private:
int &ref;
}
You can hide more complicated computations in (static) helper functions, of course, having ref(f(parameters)) in the initializer list.
If you need to create an object first and then assign it to the reference, where does that object primarily live? A reference, after all, is just someone pointing at someone else saying “that's me, over there.” If your outer object is actually the one owning this object, you don't want a reference. You either want an object or a smart pointer.
A Java reference is probably closest to C++11's std::shared_ptr, one of the smart pointers of the standard library highly recommended for everyday use. In this kind of setting, you might also want to consider std::uniqe_ptr, which has a little less overhead, but comes with limitations. Whether the fact that it requires you to create a proper copy constructor is a problem is a matter of taste – pretty often, the default constructor combined with shared_ptr is not the behavior you want, anyway.
Stay clear of std::auto_ptr, which is only in the language for backwards compatibility – it's tricky to use correctly in a lot of situations.

Related

when we have setter for setting value then why do we use parameterized constructor

When we have setter function for setting value then why do we need parameter constructor ? is it necessary to use ? is it good if we want to use constructor instead of setter and after that can we access our data using getter functions?
The job of the constructor is to construct the object in such a way that it is in a usable state. If this requires arguments to the ctor it should get them so the object can be fully formed when the constructor finishes.
Constructing an object in a partially usable state and then relying on users to remember to call specific setters before they are allowed to use the object is quite error prone.
Setters are fine for changing things after object creation but calling them should not be a requirement in order to construct a usable object.
If you do not construct a usable object upon creation, for example by using a parameterized constructor, you may run into issues if you/the user forgets to use your setters to actually give the object's parameters any real values.
It may be that you just return a bogus/zero value, which gives unexpected results, or it could cause the program to crash if you try to access some bit of memory that you don't have access to.
If I've misinterpreted your question, and you simply mean why do this:
MyClass(int a, int b) {
myPrivateIntA = a;
myPrivateIntB = b;
}
Instead of this:
MyClass(int a, int b) {
setPrivIntA(a);
setPrivIntB(b);
}
I suppose you could use the latter, if you need to do some kind of validation before setting your values.

Is it possible to trigger a computation upon a value change in C++?

Out of curiosity, I would like to know if the following class:
class Number
{
public:
double value;
double square;
};
can be changed (using custom types, proxy, ...) such as a change of Number::value would trigger the computation of Number::square, without using accessors (like Number::setValue())
I think a custom type instead of double could overload operator=, thus intercepting the assignment for a value (by the way is this the Proxy pattern?). But then I would need a way to notify the instance of the class Number that something has changed.
I'm confident that C++ is powerful enough to allow this, but maybe I'm just wrong.
Intercepting assignment to a member involves, as you speculate, to use a type with user defined assignment operator.
I have used that technique for debugging spaghetti systems. The idea is then to remove the interception once it's clear where the assignments are coming from, what order things happen in, or whatever information one is after. For it has some severe costs:
Call overhead in debug builds.
Not perfect conversion back to original type, i.e. not automatically dealing with all usage scenarios.
Precludes user code obtaining reference or pointer to the item.
In order to have assignment automatically update some other item, you need a pointer or reference to that item or containing structure. This introduces further space and execution overhead. Thus, except for the debugging scenario it's probably best to use an ordinary setter function, rather than implicit assignment interception: in general, explicit is good, implicit is bad.
Addendum: I forgot to remark on the particular usage scenario in the question, which may well be the “real” issue?
Anyway, when one value B is determined by a value A, the usual solution is to provide a function to obtain B, instead of storing the B value. If B is stored, then it should not be accessible to user code that can modify it, because that can easily attract incorrect modifications. So it should then be protected or private (preferably the latter), and using code should be offered an accessor function.
The only good reason for storing it, however, is when it's costly to compute, and in this case one wants to defer to computation until the value is requested, a "lazy" computation. So then, if the value itself cannot signal whether it's been updated, some boolean or other means to check if the value is up to date is needed. Finally, the update might be needed on a const object, and hence the stored value should be declared mutable.
Summing up, when the storage and update of B as a data item is for efficiency, with the B item as just a cache of that value, then
B should be non-public and mutable,
there should be a boolean or other means to determine if an update is needed, and
there should be a public accessor function.
These issues are quite different from the issues of implicit assignment interception. ;-)
Your proxy idea can certainly work:
class Number;
struct Proxy {
Proxy(Number *parent) : parent(parent) {}
Proxy &operator=(double d);
operator double() { return value; }
private:
Number *parent;
double value;
};
class Number
{
public:
Proxy value;
double square;
Number() : value(this) {}
// I imagine you want a double ctor too
};
Proxy &Proxy::operator=(double d) {
value = d;
parent->square = d * d;
return *this;
}
You still have a potential problem of someone assigning to square. You can add another proxy, but the hassle of all this is why it is idiomatic in C++ to use accessor functions rather than direct property access for classes that enforce invariants.
What you are doing sounds like an instance of the 'observer' or 'listener' pattern in C++
you just need a code hook from which to call 'notifyObservers' - which as you said could be in an overloaded operator= (it would naturally fit in a setter method but you prefer not to have these)

What should the default constructor do in a RAII class with move semantics?

Move semantics are great for RAII classes. They allow one to program as if one had value semantics without the cost of heavy copies. A great example of this is returning std::vector from a function. Programming with value semantics however means, that one would expect types to behave like primitive data types. Those two aspects sometimes seem to be at odds.
On the one hand, in RAII one would expect the default constructor to return a fully initialized object or throw an exception if the resource acquisition failed. This guarantees that any constructed object will be in a valid and consistent state (i.e. safe to use).
On the other hand, with move semantics there exists a point when objects are in a valid but unspecified state. Similarly, primitive data types can be in an uninitialized state. Therefore, with value semantics, I would expect the default constructor to create an object in this valid but unspecified state, so that the following code would have the expected behavior:
// Primitive Data Type, Value Semantics
int i;
i = 5;
// RAII Class, Move Semantics
Resource r;
r = Resource{/*...*/}
In both cases, I would expect the "heavy" initialization to occur only once. I am wondering, what is the best practice regarding this? Obviously, there is a slight practical issue with the second approach: If the default constructor creates objects in the unspecified state, how would one write a constructor that does acquire a resource, but takes no additional parameters? (Tag dispatching comes to mind...)
Edit: Some of the answers have questioned the rationale of trying to make your classes work like primitive data types. Some of my motivation comes from Alexander Stepanov's Efficient Programming with Components, where he talks about regular types. In particular, let me quote:
Whatever is a natural idiomatic expression in c [for built-in types], should be a natural idiomatic expression for regular types.
He goes on to provide almost the same example as above. Is his point not valid in this context? Am I understanding it wrong?
Edit: As there hasn't been much discussion, I am about to accept the highest voted answer. Initializing objects in a "moved-from like" state in the default constructor is probably not a good idea, since everyone who agreed with the existing answers would not expect that behavior.
Programming with value semantics however means, that one would expect
types to behave like primitive data types.
Keyword "like". Not "identically to".
Therefore, with value semantics, I would expect the default
constructor to create an object in this valid but unspecified state
I really don't see why you should expect that. It doesn't seem like a very desirable feature to me.
what is the best practice regarding this?
Forget this idea that a non POD class should share this feature in common with primitive data types. It's wrong headed. If there is no sensible way to initialize a class without parameters, then that class should not have a default constructor.
If you want to declare an object, but hold off on initializing it (perhaps in a deeper scope), then use std::unique_ptr.
If you accept that objects should generally be valid by construction, and all possible operations on an object should move it only between valid states, then it seems to me that by having a default constructor, you are only saying one of two things:
This value is a container, or another object with a reasonable “empty” state, which I intend to mutate—e.g., std::vector.
This value does not have any member variables, and is used primarily for its type—e.g., std::less.
It doesn’t follow that a moved-from object need necessarily have the same state as a default-constructed one. For example, an std::string containing the empty string "" might have a different state than a moved-from string instance. When you default-construct an object, you expect to work with it; when you move from an object, the vast majority of the time you simply destroy it.
How would one write a constructor that does acquire a resource, but takes no additional parameters?
If your default constructor is expensive and takes no parameters, I would question why. Should it really be doing something so expensive? Where are its default parameters coming from—some global configuration? Maybe passing them explicitly would be easier to maintain. Take the example of std::ifstream: with a parameter, its constructor opens a file; without, you use the open() member function.
What you can do is lazy initialization: have a flag (or a nulled pointer) in your object that indicates whether the object is fully initialized. Then have a member function that uses this flag to ensure initialization after it is run. All your default constructor needs to do is to set the initialization flag to false. If all members that need an initialized state call ensure_initialization() before starting their work, you have perfect semantics and no double heavy initialization.
Example:
class Foo {
public:
Foo() : isInitialized(false) { };
void ensureInitialization() {
if(isInitialized) return;
//the usual default constructor code
isInitialized = true;
};
void bar() {
ensureInitialization();
//the rest of the bar() implementation
};
private:
bool isInitialized;
//some heavy variables
}
Edit:
To reduce the overhead produced by the function call, you can do something like this:
//In the .h file:
class Foo {
public:
Foo() : isInitialized(false) { };
void bar();
private:
void initialize();
bool isInitialized;
//some heavy variables
}
//In the .cpp file:
#define ENSURE_INITIALIZATION() do { \
if(!isInitialized) initialize(); \
} while(0)
void Foo::bar() {
ENSURE_INITIALIZATION();
//the rest of the bar() implementation
}
void Foo::initialize() {
//the usual default constructor code
isInitialized = true;
}
This makes sure that the decision to initialize or not is inlined without inlining the initialization itself. The later would just bloat the executable and reduce instruction cache efficiency, but the first can't be done automatically, so you need to employ the preprocessor for that. The overhead of this approach should be less than a function call on average.

Why does void setOutputFormat(ostream out, int decimal_places) cause an error?

If I change it to void setOutputFormat(ostream& out, int decimal_places),
with a call by reference, it works. I don't understand why though?
What is the difference between a struct and a class, besides struct members are by default public, and class members are by default private?
You're right that there is no difference between class and struct, except the default private vs private.
The problem here is that ostream doesn't have a copy constructor, so you can't pass it by value.
When you attempt to pass the ostream by value, you attempt to make a copy of the stream, which is not valid because stream objects are noncopyable, that is, they do not define a copy constructor. When you pass the stream by reference, however, the function receives a modifiable alias to the ostream instance. Take for instance:
void increment(int n) {
// Increment local copy of value.
++n;
}
int x = 5;
increment(x);
// x is still 5.
Versus:
void increment(int& n) {
// Increment value itself.
++n;
}
int x = 5;
increment(x);
// x is now 6.
So passing the stream by reference is the only way that makes sense, since you want setOutputFormat to modify the original stream in-place. Hope this clarifies the issue somewhat.
As other said, you're trying to create a copy of a noncopyable object (the stream), which results in that error.
In C++ when you pass a var as a parameter, you make a copy of it (opposed to C#, where, for reference types, you're always implicitly passing a reference to it).
By default C++ provides a bitwise copy constructor for every class, but often it's not what is required: think, for example, to a class that owns a resource handle: if you make a perfect clone of an object of that type you'll have two class who think to own such resource, and both will try to destroy it at their destruction, which clearly isn't nice.
Because of this, C++ lets you provide a copy constructor for each class, which is called when a copy of an object has to be created. Since for many objects (streams included) creating copies isn't desired (because it makes no sense, because it's not convenient or because the trouble isn't worth the work) often the copy constructor is disabled (by marking it as private or protected), and you can't create copies of such objects.
Moreover, in general you must be careful with assignments and copies by value with object belonging to complicated class hierarchies, because you may incur in object slicing and other subtle problems. Actually, it's common practice to block copy and assignment in classes intended to be base classes.
The solution, in most cases (including yours) is to pass such objects by reference, thus avoiding making copies at all; see #Jon Purdy's answer for an example.
By the way, often even with copyable objects (e.g. std::strings) it's better to just pass references, to avoid all the work associated with copying; if you're passing a reference just for the sake of efficiency but you don't want to have your object modified, the best solution usually is a const reference.
Copies are also used in some other places in C++; I advise you to have a look at wikipedia page about copy constructors to understand a bit better what's going on, but, over all, to grab a C++ book and read it: C# is different from C++ in a lot of ways, and there are many fake-similarities that may confuse you.

Constructors accepting string reference. Bad idea?

It's considered a bad idea/bad design, have a class with a constructor accepting a reference, like the following?
class Compiler
{
public:
Compiler( const std::string& fileName );
~Compiler();
//etc
private:
const std::string& m_CurrentFileName;
};
or should I use values?
I actually do care about performance.
If you used a value parameter in this case, you would have a reference in the class to a temporary, which would become invalid at some point in the future.
The bad idea here is probably storing a reference as a member in the class. It is almost always simpler and more correct to store a value. And in that case, passing the constructor a const reference is the right thing to do.
And as for performance, you should only care about this where it matters, which you can only find out by profiling your code. You should always write your code firstly for correctness, secondly for clarity and lastly for performance.
It's fine as long as the constructor either just uses it without retaining it, copies it for further use (at which point, using a reference probably doesn't matter), or assumes ownership of it (which is iffy because you're depending on the user to behave correctly and not use the string reference further).
However, in most cases, the string copy probably won't be a bottleneck and should be preferred for bug avoidance reasons. If, later, you can PROVE that it's a bottleneck (using profiling, for instance), you might want to think about fixing it.
If you can guarantee that the string that the reference uses won't go out of scope until the class does, then it is maybe Ok to use (I wouldn't). If you were having issues, you may be better passing the string around with a reference counted smart pointer.
It may be worth, and safer, writing your application so that the class constructor copies the string, then when you have performance issues, profile them. Most of the time it is not this sort of thing that causes the issues, but at the algorithm and data structure level.
While passing the parameter via a const reference is a nice thing (you should do that in most cases), storing it as a const reference is dangerous -- if the object passed ceases to exits, you might get a segfault.
Also remember -- premature optimization is the root of all evil! If you have performance issues after writing working code, use a tool like gprof to find where the bottleneck is. And from experience I can tell that the bottleneck almost always will be in bad design, and not a bad language use.
I agree with other people that you should be more concerned about correctness and robustness over performance (so the member variable should be a copy, not a reference) and that if you're really concerned about performance, you should profile your code.
That said, it's not always clear-cut that passing by const reference is faster. For example, if you pass by value instead and if the argument is an rvalue, the compiler can do copy elision (see http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/) and avoid an extra copy when you save it to the member variable. (This isn't very intuitive, and it's probably not something you'd want to do everywhere, so again: profile!)
If you are writing a compiler, copying the filename once or twice will not be the bottleneck. This is more of a C++ style issue, which I leave to the more C++ savvy people around here.
Your class must be self-contained, and avoid unnecessary dependencies. In your example, your "Compiler" class will depend on the CurrentFileName string for its whole existence. Meaning that if CurrentFileName is destroyed before Compiler, you'll have a problem.
Dependents & Managers
So, I guess is depends on the nature of the dependency between the Dependent class and it Manager class (i.e. the Dependent class depends on the Manager class, or, in your example, the Compiler class depends on the std::string class)...
If the dependency is "soft", then Dependant should make a copy of Manager class.
If the dependency is "strong", then Dependant could have a reference to the Manager class.
Soft vs. Strong
An example of "soft dependency" is when your Dependant needs only a value, not the exact object itself. A string is usually seen as a value.
An example of "strong dependency" is when your Dependant needs to have access to its Manager, or when rhe Dependent has no meaning without a Manager (i.e. if the Manager is destroyed, then all Dependents should have been destroyed before)
Conclusion
Usually, the dependency is soft.
If in doubt, considers it soft. You'll have less problems (this is one of the way to have a pretty C++ segfault without pointer arithmetics), and still have the possibility of optimize it if needed.
About your case: Soft
Do yourself a favor, and make a copy of the value.
Optimization is the root of all evil, and unless your profiler says the copy of the string is a problem, then, make a copy, as below:
class Compiler
{
public:
Compiler( const std::string& fileName ); // a reference
~Compiler();
//etc
private:
const std::string m_CurrentFileName; // a value
};
Compiler::Compiler(const std::string& fileName )
: m_CurrentFileName(fileName) // copy of the filename
{
}
About my case: Strong
Now, you could be in a situation where the Dependent's existence has no meaning without the Manager itself.
I work currently on code where the user creates Notifier objects to subscribe to events, and retrieve them when needed. The Notifier object is attached to a Manager at construction, and cannot be detached from it.
It is a design choice to impose to the library user the Manager outlives the Notifier. This means the following code:
Manager manager ;
Notifier notifier(manager) ; // manager is passed as reference
The Notifier code is quite similar to the code you proposed:
class Notifier
{
public :
Notifier(Manager & manager) : m_manager(manager) {}
private :
Manager & m_manager ;
} ;
If you look closely at the design, the m_manager is used as an immutable pointer to the Manager object. I use the C++ reference to be sure:
The reference is defined at construction, and won't ever be changed
The reference is never supposed to be NULL or invalid
This is part of the contract.
If you are highly concerned about performance then passing by reference is the better approach .
Think about following example to make picture more clear:
class A{
public : A() {}
};
class B : public A{
public : B() {}
};
class MyClass{
B bObj;
public:
MyClass(B b) : bObj(b) { } // constructor and destructor overhead
MyClass(B &b) { }
};