Cherno-C
Cherno-C
Also if we have defined some variable globally then to use it another cpp, we have
to use extern. But if we make that variable as static then it will show error after
using extern as
well because now it will become private in first translation unit.
"" can be used for any header file but <> will be used for files we have to look it
in include directory
We cant assign reference variable to another variable, what it will do is assign
the older variable to the new variable value.
Enums are the data types that gives names to integer constants. It is helpful when
we want certain values to be represented as states or something meaningful.
enum will give error if we use similar word which is present outside or two enums
can't have the same word but this we can do in enum class as we use scope
resolution in that case.
const char* name = "Cherno" - Here it will automatically add null character in the
end
char name[6] = {'c','h','e','r','n','o'} - Here we should add null character
explicitily and make size 7, otherwise cout wont know where to end and it will
print some extra junk value
string s = "vivek" + "cherno" - not possible as cant add two const char*, so -
std::string("vivek") + "cherno"
but now from C++14 possible - using namespace std::string_literals
string s = "vivek"s + "cherno"
const int val = 40; this can be modified via casting it to int*.
int* p = (int*)&val; and then p value can be changed.
1. const int* p = &val; or int const* p = &val; This means content cant be
changed . *p = 30; - Error
2. int* const p = &val. This means pointer can not be reassigned. p =
&somethingelse; - Error
In const function if we have to modifiy some variable , for ex- counter, then we
can make that variable as (mutuable int counter).
Also when we create lambda with value, we cant modify with the same variable name
that is outside, so either we create new variable inside lambda and assign outside
variable to it
or we can mark lambda mutuable then we can use the outside variable only, it will
behave as a new element only.
int x = 8;
auto f[]=[=](){
x++; - Error
}
auto f[]=[=](){
int y = x;
y++;
}
OR
auto f[]=[=]() mutuable{
x++; Works , also this x will be a copy
}
Entity(string x)
{
s = x; - > here again constructor will be called.
}
In initializer list, only once it will be done.
Smart Pointers
Unique pointer is scoped pointer, it will be destroyed after getting out of scope.
std::unique_ptr<Entity> u = std::make_unique<Entity>() is better than
std::unique_ptr<Entity> u(new Entity()); because of exception safety in case of
constructor throws
exception and we will be having dangling pointer in the second case.
How to use -
std::weak_ptr<Entity> obj = e; where e is shared pointer
shared_ptr<Entity> s = obj.lock();
if(s.expired())
{
// use here . It does not increase the count;
}
Weak ptr can be used in case of removing cyclic dependencies. Cycle dependencies is
when we assign one shared pointer to another shared_ptr and vice versa.
struct A{
shared_ptr<B> ptrB;
};
struct B{
shared_ptr<A>ptrA;
};
int main()
{
shared_ptr<A> p1 = make_shared<A>();
shared_ptr<B> p2 = make_shared<B>();
p1->ptrB = p2;
p2->ptrA = p1;
}
We need to create one weak pointer in those struct , then both will be destroyed
after scope ends otherwise no one destroys and memory leak.
Function pointers
* Functions are CPU instructions , so we pass the address of those cpu
instructions.
void print()
{
cout<<"hello";
}
void(*helloworldfucntion)();
helloworldfucntion = print;
or
void(*helloworldfucntion)() = print;
Lambda function
Whenever we are using function pointer, we can use lamdas instead of that. It is
like a throw away function
In case we have to call that function somewhat later with some conditions in place,
which is present in different function, then we pass lambda or function pointer.
auto lambda = [](int value){
std::cout<<"Hello";
}
if we want to pass this, receiving end can be function pointer or auto.But if we
are passing it by value or reference then receiving end should have std::function
const std::function<void(int)>& func;
Casting
dynamic casting is used when we try to assign parent class pointer to child class
pointer or vice - versa. It is mostly helpful in the first case.
Because we did not know wheather parent is type of child1 or child2 or parent type.
const casting is when you try to assign const pointer to non-const pointer.
reinterpret cast is when you assign one type of pointer to other (for ex - int* to
char*)(meaning two different types)
static cast is used to do explicit casting which is safe as per compiler.
Move Semantics
L value is something which has location in memory.
int & x = 10; //error
const int& x = 10; works
std::string && name - r value reference
*noexcept is used when we are sure that function will not throw any exception , to
give compiler hints for optimisation(because it will
remove exception headers and all). But if function throws any exception then
compiler will shut down/termiante whole application.
Union,Enum
Threads
STL
Sorting
Linkedlist