C++11, is default member construction a good thing? [closed] - c++

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Since C++11 we can default construct our variables in a class, like this:
class Foo{
private:
int bar = 0;
};
I've very rarely seen someone using this feature
Is this a good practice ?

This is a style question, but there are some considerations that are hopefully universal:
If all constructors of your class have to initialize a member the same way, because the initial value is in some profound way part of the invariants of the class, then it is both more readable and self-documenting and also shorter to use the inline initializer, and the deduplication removes a source of errors if you ever need to change the initial value.
Otherwise, if different constructors supply different initial values, then you shouldn't have an inline initializer, even though that's technically permitted.

I dont see any bad practices in this approach. This is allowed even in Higher level languages like Java. It reduces lines of code inside constructor.

The only big disadvantage I see is that it may lead people to expose more implementation details than necessary in class definitions. Currently, if you initialize a member in MyClass.cpp, then you can easily change the value later on. If you initialize the member in MyClass.h, then a lot of recompilation could be necessary if you later change the value.
In Java, you don't have this kind of separation between header and implementation, so the situation cannot be compared to C++.

C++11 allows non-static data members to be initialized in-class.
This can often save some typing. Consider the following example:
class Foo {
public:
Foo() : a_{5}, b_{7}, s_{"Foo"}, bar_{"Test"} {}
Foo(int x) : a_{x}, b_{7}, s_{"Foo"}, bar_{"Test"} {}
Foo(double d) : a_{5}, b_{g(d)}, s_{"Foo"}, bar_{"Test"} {}
int someFunc();
private:
int a_;
int b_;
std::string s_;
Bar bar_;
};
Using in-class initialization will IMHO make the code more readable.
class Foo {
public:
Foo() = default;
Foo(int x) : a_{x} {} // Initialization list overrides in-class initialization.
Foo(double d) : b_{g(d)} {} // Same here.
int someFunc();
private:
int a_ = 5;
int b_ = 7;
std::string s_{"Foo"};
Bar bar_{"Test"};
};
I would say use it when possible. An exception is when the situation described in this answer applies.

Related

Initialization without recursion [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 3 years ago.
Improve this question
I'm trying to do a bit of refactoring and I am curious about how would you approach this problem.
Basically I'm trying to create an initialization function for each class. There are classes that inherit from some others, and i would like to use parent initialization function if possible. How would you address this?
I would like to use these structs with memcpy and maybe using also them with the keywords align and __attribute__((packed)); and they must be usable with extern "C". I would exclude then constructors and destructors.
An example to explain:
struct A
{
int a;
};
void initialize(A& a)
{
a = 0;
}
struct B : A
{
int b;
};
void initialize(B& b)
{
initialize(b); // here I want void initialize(A& a), not recursion
b = 0;
};
Maybe I have to do some kind of cast? Ideally I'm looking a solution that does not create overhead.
Use a static_cast.
In your code, the initialize(b) call will recurse infinitely, because b is better matched as B& than as A& (the argument of the function you want to call), thus the overload resolution picks the same function and recurs.
You specified that you want to initialise the A part of the b object. Why not tell that to the compiler? Tell it that you want to call initialise in it as though it was an A, like so:
initialize(static_cast<A&>(b));
As for your concern that you mentioned in the comment - no copies are being made here. If I used static_cast<A>, however, a temporary object would be created, but that's not the case. I am not casting b to an object of a type A. I am casting it to a reference of a type A, which will result in creation of temporary reference. Since A& matches with A& better than with B&, the first function will be chosen, thus avoiding the recursion.

PIMPL idiom clarification [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
While trying to remove all implementation details from a header file I decide to use and try out PIMPL idiom. The majority if not all examples, e.g. cppreference, I've seen use levels of indirection which reason I can't understand besides encapsulation. The examples always come with this flavor pattern.
Typical
//A.hpp
class A
{
public:
A(int);
//More non-static class methods
void set(int);
private:
struct a_impl;
std::unique_ptr<struct a_impl> pimpl;
};
//A.cpp
struct A::a_impl
{
private:
int i;
public:
a_impl(int i) : i{i}{}
//More non-static implementation class methods
void set(int i) {this->i = i;}
};
A::A(int i) : std::make_unique<struct a_impl>(i) {}
A::set(int i) {pimpl->set(i);} //????
A:://More indirect calls to non-static member functions through pointer
At certain point I start wondering why do I need all this level of complexity and indirection if we are talking about implementation. Why not something simplest without all those indirect calls.
Why not ?
//A.hpp
class A
{
public:
A(int);
//.....
void set(int);
private:
struct a_impl;
std::unique_ptr<struct a_impl> pimpl;
};
//A.cpp
struct A::a_impl
{
int i;
}
A::A(int i) : std::make_unique<struct a_impl>() { pimpl->i = i; }
A::set(int i) { pimpl->i = i; } //!!!!
What I would like to clarify:
1-Are all this samples presented this way just for a matter of education and good encapsulation practices?
2-Is there any other good reason I'm missing to add this level of complexity and overhead besides question 1?
3-Or what I put out as an alternative isn't PIMPL idiom?
Your own approach and the one you compare it against are just two different flavors of the idiom. Herb Sutter listed them, and more, in GotW #100:
What parts of the class should go into the impl object? Some potential
options include:
put all private data (but not functions) into impl;
put all private members into impl;
put all private and protected members into impl;
put all private nonvirtual members into impl;
put everything into impl, and write the public class itself as only the public interface, each implemented as a simple forwarding function
(a handle/body variant).
Each has its own strong and weak points. For the case you study, your approach does seem better. For other cases, a pimpl with behavior and not just state may be more appropriate. There isn't really a one size fits all.

Why C++ allows returning a reference to private members [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
class test {
public:
test(int value = 0): x(value) {}
int& get(){
return x;
}
private:
int x;
};
this will allow client code to mutate the private members
this is legal in C++, but why ?
Is there any situation where you would actually need to break the class encapsulation ?
Make a member as private, means you can not access it directly. But nothing restricts you to access it indirectly via a public member. It depends on you design. You can even do this:
class test {
public:
test() : x(y) {}
int &x;
private:
int y;
};
In your class, assume you want count how many times a member is read/write. So, you can make it private then put a member function which returns a refernce to the variable:
class test {
public:
test(int value = 0): x(value), count(0) {}
int& get(){
count++;
return x;
}
private:
int x;
int count;
};
I hope this example shows how making a member as private and then putting an indirect access to it can be useful.
Ffirst of all let's consider implementing what you describe. It would be very onerous to properly do so. Your example is easy enough. But what if the reference flowed through a number of functions before it reached the function that exposed it? The compiler would have to do exceptionally complex static analysis, beyond the levels of static analysis that are reasonable to expect from compiler writers.
So even if the designers wanted to ban this, it would not have been tractable to do so. Would the designers have wanted to stop this? Very doubtful. Had they done so, how would the [] operator be implemented on a container or a string?
Is there any situation where you would actually need to
break the class encapsulation
As example of the [] operator on containers and strings shows, this feature is in fact used to support encapsulation.
Why? Because C++ mainly tries to let you do whatever you want and not get in your way; it doesn't try very hard to keep you safe. If you want a safe language, use something else. You have something like object-orientation if you want to, but if you want to break out of that, more power to you. With great power comes great responsibility.
It's worth nothing that you don't even need this to break encapsulation; you could simply reinterpret a pointer to "test" as an integer and access the private field this way.

What does this small chuck of code mean? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have this chuck of code and I'd really appreciate if someone could help me out by giving some more information about what it is. I know a bit of coding, but not too much so please bear with me if this seems silly.
class A
{
public:
A();
};
int x, y, z;
A::A():
x(1),
y(2),
z(3)
{
//some code here basically more variable definition
}
What I don't get is this,
a function which is also the name of a class? Even if it works, but why would I want to do that?
what is up with the variable definition of x, y, z. I assume some constructors are being called, but what's wrong with defining them the normal way?
And what does do they being after the colon : but before the function definition signify?
Thank you. Much appreciated.
Really, a C++ tutorial is what you need, but here goes:
A "function" with the same name as the class is a constructor. There can be several of these, each taking different arguments. In this case, the constructor takes no arguments at all (and so is called a default constructor). Not all classes have a default constructor, but if you don't write any constructors of your own, then the compiler will create a default constructor for you.
The bit after the colon is a special bit of syntax used in constructors. It's called an initializer list. What happens is that before you get to the body of the constructor, the member variables listed are initialized with those values (or, in the case of objects, constructors are called with those arguments). You should always use an initializer list to set the values of variables if you can.
In this case then, the default constructor specifies that the member variables x, y and z should be initialized to 1, 2 and 3 respectively (at least I assume they're meant to be member variables -- as written, they're actually globals).
What you have in your question isn't valid C++.
class A
{
public:
A();
};
int x,y,z; // x,y,z are out here in the wild
// This is supposed to be the definition of the constructor of "A"
// outside the "A" class
//
// The "A::A() : " sequence introduces a list of member initializers.
A::A() :
x(1), // <- These are not members of "A", so they cannot be initialized as members!
y(2), // <-
z(3) // <-
{
}
What I think you meant was:
class A
{
public:
int x,y,z;
A();
};
A::A() :
x(1), // <- Now members of "A", so they can be initialized here
y(2), // <-
z(3) // <-
{
}

How to organize a class's member functions? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I put 'sets' just after the constructors because it is related to the object setup. I split gets (put gets in inquires) and sets but not sure if this is good or not. What is best practice for organizing member functions?
How about that?
class Foo
{
// Friends go here if it has
friend ...;
friend ...;
// First public, then protected and private
public:
// enums
enum {...}
// type defines.
typedef ...;
...
// Destructor and constructors
~Foo();
Foo(...);
Foo(...);
...
// Sets.
void setA(...);
void setB(...);
void setC(...);
...
// Inquiries (including gets).
A a() const;
B b() const;
...
// Operators.
void operator()(...);
...
// Operations.
void doSomething();
...
protected:
private:
};
It's hard to judge, it's up to your personal preference or company coding standard. By looking at your code, a few things I may not agree:
your declarations are not ordered from pubilc,'protected` then private
friend declaration has same effort when you declare them in private area as well. so I normally put them in private section, so it gives less noise in public section.
Below is the declaration order I normally use:
Use the specified order of declarations within a class: public: before private:, methods before data members (variables), etc.
class definition should start with its public: section, followed by its protected: section and then its private: section. If any of these sections are empty, omit them.
Within each section, the declarations generally should be in the following order:
Typedefs and Enums
Constants (static const data members)
Constructors
Destructor
Methods, including static methods
Data Members (except static const data members)
Friend declarations should always be in the private section, and the disabled copy constructor and other operators `should be at the end of the private: section. It should be the last thing in the class.