> What if we even don't declare these? Aren't these exactly those which the compiler
> implicitly creates when there isn't any? If yes, so we can drop them, not?
If we do not declare a default constructor, the class will not be
DefaultConstructible The compiler will provide an implicitly declared default constructor if and only if there are no user-declared constructors at all.
> By custom it means the ones we ourselves create not the default ones that are created by the compiler
Yes. User defined destructors, copy/move constructors and copy/move assignment operators.
> And why does it have used "encapsulated"?
In this context, it means that correctly copying or moving an object, assigning one object to another, and performing proper clean up when the life-time of the object is over is the responsibility of the writer of the class. To the user of the class, these are implementation details that the user does not have to worry about.
> Does it because implicitly created constructors, destructors, copy/move constructors,
> copy/move assignment operators all do a shallow copy and not deep copy?
Semantically, implicitly defined copy/move constructors perform a member-wise copy/move; and implicitly defined assignment operators perform a member-wise assignment.
That means that for a member object of type
std::string, the appropriate operation defined by
std::string would be used; this would be a 'deep' copy.
For a member object which is a raw pointer, the pointer would be copied. The object pointed to would not be copied; this would be a 'shallow' copy.
Moral of the story: use
std::string,
std::vector etc. or a smart pointer instead of raw 'owning' pointers.
> Can we say we should replace using unsigned int with size_t in all cases or only loops and indexing?
Ideally, use
std::size_t for specifying the size of an array/object or an index into an array. We can also use
std::size_t for this purpose with standard library containers (when the allocator is the default allocator). In other places, use types like
int or [tt[unsigned int[tt]
Note: use [tt]std::ptrdiff_t[/tt] to represent the result of subtracting one ppointer from another or a possibly negative offset.
http://en.cppreference.com/w/cpp/types/ptrdiff_t
> Why using std:: for types but not a more convenient remedy:
> declaring using namespace std; at the beginning of the code?
Do not use using declarations and directives in a header file or in any file before a
#include directive.
Other than that, there are two valid points of view:
One which says that using declarations and directives are perfectly acceptable in implementation files, especially if it is local to a scope; if you perceive that it aids readability, use it.
In short: You can and should use namespace using declarations and directives liberally in your implementation files after #include directives and feel good about it. Despite repeated assertions to the contrary, namespace using declarations and directives are not evil and they do not defeat the purpose of namespaces. Rather, they are what make namespaces usable.
...
But using declarations and directives are for your coding convenience, and you shouldn't use them in a way that affects someone else's code. In particular, don't write them anywhere they could be followed by someone else's code: Specifically, don't write them in header files (which are meant to be included in an unbounded number of implementation files, and you shouldn't mess with the meaning of that other code) or before an #include (you really don't want to mess with the meaning of code in someone else's header).
- Sutter and Alexandrescu in 'C++ Coding Standards: 101 Rules, Guidelines, and Best Practices' |
SF.6: Use using namespace directives ... for foundation libraries (such as std) ...
using namespace can lead to name clashes, so it should be used sparingly. However, it is not always possible to qualify every name from a namespace in user code (e.g., during transition) and sometimes a namespace is so fundamental and prevalent in a code base, that consistent qualification would be verbose and distracting.
CoreGuideLines https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rs-using
|
The other, which says that using explicit namespace prefixes, even in implementation files, makes the code clearer, and more portable.
In implementation files (e.g. .cpp files), the rule is more of a stylistic rule, but is still important. Basically, using explicit namespace prefixes makes the code clearer, because it is immediately obvious what facilities are being used and where they are coming from. And more portable, because namespace clashes cannot occur between LLVM code and other namespaces. The portability rule is important because different standard library implementations expose different symbols (potentially ones they shouldn't), and future revisions to the C++ standard will add more symbols to the std namespace. As such, we never use 'using namespace std;' in LLVM.
- LLVM Coding Standardsre portable. |
I belong to the second school (using explicit namespace prefixes, even in implementation files, makes the code clearer, and more portable); so that is what I tend to do most of the time.
Think about it, and then follow what appeals to you more.