Skip to content

Commit 9a4211d

Browse files
committed
Refactor namespace section
1 parent 1f5ad91 commit 9a4211d

File tree

1 file changed

+48
-59
lines changed

1 file changed

+48
-59
lines changed

C++ Syntax.md

Lines changed: 48 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -716,8 +716,8 @@ int main() {
716716
You can also similiarly overload the input stream operator (`>>`), and can read more about the various operators [here](http://en.cppreference.com/w/cpp/language/operators).
717717
718718
### 1.6 Templates
719-
Templates are a very powerful abstraction allowing you to generate compile-time methods for any number of types by providing only
720-
one implementation.
719+
Templates are a very powerful abstraction allowing you to generate compile-time methods/classes/etc. for any number of types while
720+
writing only one implementation.
721721
722722
Say you have a method that adds two floating point number together, and another to add two integers together:
723723
@@ -731,9 +731,9 @@ int Add(const int a, const int b) {
731731
}
732732
```
733733

734-
That's great, but since both floating point numbers and integers implement the `+` operator and it has the same syntactic meaning,
735-
you can use a template to instead write one generic implementation of a method that can operate on doubles, ints, floats, and (in this
736-
case) any other type that implements the `+` operator.
734+
That's great, but since both floating point numbers and integers implement the `+` operator you can use a template to instead
735+
write one generic implementation of a method that can operate on doubles, ints, floats, and (in this case) any other type that
736+
implements the `+` operator.
737737

738738
A simple templatized version of `Add` would look something like this:
739739

@@ -755,6 +755,9 @@ int main() {
755755
}
756756
```
757757
758+
In this simple example the compiler would generate four different methods, one for each type. Templating allows you to write more
759+
concise and modular code at the expense of generating a larger executable (code bloat).
760+
758761
Templates are especially useful to create class templates. Class templates must be completely defined in a single header file.
759762
760763
```c++
@@ -782,85 +785,71 @@ Read more about templates [here](https://www.geeksforgeeks.org/templates-cpp/) a
782785

783786
## 2.0 General C++ Syntax
784787
### 2.1 Namespaces
785-
In big projects, there are thousands of variables, and each needs it's own name. Let's imagine that there are library with linked list structure, and we need to somehow represent single node of a list:
786-
```c++
787-
// file named "LinkedList.h"
788-
template <typename T> // use of templates
789-
struct Node { // pretty and short name
790-
Node* next;
791-
Node* prev;
788+
In a large production project you may have thousands of symbols for various types, variables, methods, and so on. To avoid symbol names conflicting
789+
with one another you can use namespaces to logically separate symbol names in to broad categories. Namespaces are an inherent feature of C++; when you
790+
create a class and refer to a method as `ClassName::Method()` you are essentially using a namespace feature intrinsic to classes.
792791

793-
T data;
794-
};
795-
```
796-
And there are library with binary search tree structure:
797-
```c++
798-
// file named "BST.h"
799-
template <typename T>
800-
struct Node {
801-
Node* left;
802-
Node * right;
792+
For a brief namespace example, suppose that you have two data structures, both of which implement a `Node` class. In the following code, namespaces
793+
are used to allow the compiler (and the programmer) to distinguish between the two types.
803794

804-
T data;
805-
};
806-
```
807-
We want to create our project that uses both of this libraries:
808795
```c++
809-
#include "LinkedList.h"
810-
#include "BST.h"
796+
// File: list.h
797+
798+
namespace list {
811799

812-
int main()
813-
{
814-
Node<int> * a = new Node<int> {nullptr, nullptr, 3}; // oops
815-
};
816-
```
817-
How do compiler know what Node we are about to use? `namespace` comes to the rescue:
818-
```c++
819-
// "LinkedList.h"
820-
namespace lst {
821800
template <typename T>
822801
struct Node {
823-
// ...
824-
};
802+
Node * next;
803+
Node * prev;
804+
T data;
825805
};
806+
807+
}; // namespace
826808
```
827-
and
809+
828810
```c++
829-
// "BST.h"
811+
// File: bst.h
812+
830813
namespace bst {
814+
831815
template <typename T>
832816
struct Node {
833-
// ...
834-
};
817+
Node * left;
818+
Node * right;
819+
T data;
835820
};
821+
822+
}; // namespace
836823
```
837-
and usage is:
824+
838825
```c++
839-
#include "LinkedList.h"
840-
#include "BST.h"
826+
// File: main.cpp
827+
#include "list.h"
828+
#include "bst.h"
841829

842-
int main()
843-
{
844-
lst::Node<int> * a = new lst::Node<int> {nullptr, nullptr, 3}; // it is linked list node
845-
bst::Node<int> * a = new bst::Node<int> {nullptr, nullptr, 3}; // it is bst node
830+
int main() {
831+
list::Node<int> a;
832+
bst::Node<int> b;
846833
};
847834
```
848-
So now you could specialize, and don't be afraid of name collisions, just use simple, pretty names.
849-
By the way remember `std::cout`? It is object of `namsepaces std`, it is recommended to use full namespace names almost everywhere, because you are sure what structure you are using. But if it is your small(very small) project you could try:
835+
836+
The standard C++ library uses the namespace `std`, e.g. `std::cout`, `std::string`, `std::endl`, etc. While you can use a `using namespace foo;` directive to address
837+
symbols directly in the `foo` namespace without prefixing the `foo::` qualifier, this is generally considered bad practice as it pollutes the global namespace and
838+
sort of undermines the point of using namespaces in the first place.
839+
850840
```c++
851841
#include <iostream>
842+
using namespace std;
852843

853-
using namespace std; // everything inside namespace std becomes visible
844+
cout << "Hello, World" << endl; // <--- BAD: pollutes the global namespace
845+
```
854846

855-
int main()
856-
{
857-
cout << "Hello, namespace!"
847+
```c++
848+
#include <iostream>
858849

859-
return 0;
860-
}
850+
std::cout << "Hello, World" << std::endl; // <--- GOOD: It's clear that you're using symbols from the standard namespace
861851
```
862852

863-
864853
### 2.2 References and Pointers
865854
are used to store the address of the varibale/object in memory. So having the pointer or reference, you could do the same operations as that of object being pointed to.
866855
```c++

0 commit comments

Comments
 (0)