C++ Course: Beginning C++ Programming – From Beginner to Beyond: Udemy

Some parts from beginning are written in my wiki.

07.05.2022:

Default constructor parameters

//copy constructor
//pass object by value
Player hero{"Hero", 100, 20};

void display_player(Player p)
{

}

display_player(hero);



//return object by value
Player enemy;
Player create_super_enemy(){
	Player an_enemy{"Super enemy", 1000, 1000};
	return an_enemy; //A copy of an_enemy is return
}

enemy = create_super_enemy();

//construct one object based on another
Player {"hero", 100,100};
Player another_hero{hero}; //A copy of hero is made

//declaring copy consturctor
Type::Type(const Type &source);

Player::Player(const Player &source);

Account::Account(const Account &source);

//Implementing copy constructor
Type::Type(const Type &source){

	//code or initialization list to copy the object
	
}


Player

Player::Player(const Player &source)
:name{source.name},
health{source.heath},
xp{source.xp}{}

Smart Pointers:

Unique pointer: It take the full heap memory and works there 
//unique_ptr - creating, initializing and using


{

	std::unique_ptr<int> p1 {new int {100} };
	
	std::cout<<*p1<<std::endl; //100
	
	*p1=200;
	std::cout<<*p1<<std::endl; //200
} //here it is automatically deleted 



//unique pointer method

{

	std::unique_ptr<int> p1 {new int {100}};
	
	std::cout<<p1.get()<<std::endl; //0x567588
	
	
	p1.reset(); //p1 is now nullptr
	
	
	if(p1)
		std::cout<<*p1<<std::endl; //won't execute

} //automatically deleted 


//user defined class

{
	std::unique_ptr<Account> p1 {new Account {"Larry"}};
	std::cout<<*p1<<std::endl; //display account
	
	
	p1->deposit(1000);
	p1->withdraw(500);
	


}

unique_ptr -make_unique(C++14)


{

	std::unique_ptr<int> p1 = make_unique<int> (100);
	std::unique_ptr>Account> p2= make_unique<Account>("Curly", 5000);
	
	
	auto p3=make_unique<Player>("Hero" 100, 100);


}//automatically deleted
#include<iostream>
#include<memory>
#include<vector>

#include "Account.h"
#inlcude "Checking_Account.h"
#include "Trust_Account.h"
#include "Savings_Account.h"


class Test
{
private:
 int data;
 
public:
	Test(): data{0} {std::cout<<"Test constructor("<<data<<")"<<std::endl;}
	Test(int data):data(data) {std::cout<<Test constructor("<<data<<")<<std::endl; }
	int get_data() const {return data;}
	~Test(){std::cout<<"Test destructor("<<data<<")<<std::endl;}
	
	
};

using namespace std;

int main()
{
	Test *t1=new Test{1000};
	
	delete t1;
	
	
	std::unique_ptr<Test> t1 {new Test(100}};
	std::unique_ptr<Test> t2 = std::make_unique<Test>(1000);
	
	return 0;

}

Shared pointer: It works on half of the heap memory

//shared ptr--creating,initializing and using


{

	std::shared_ptr<int> p1{new int {100}};
	std::cout<< *p1 <<std:.endl;
	
	*p1=200;
	
	
	std::cout <*p1<<std::endl;
	

};

Weak Pointer:

//Weak pointer, cicular pointer
#include<memory>
#include<iostream>


class B;

class A{
	std::shared_ptr<B> b_ptr;
public:
	void set_B(std::shared_ptr<B> &b){
	
		b_ptr=b;
	}
	A() {cout<<"A constructor"<<endl; }
	
	~A() {cout<<"A constructor"<<endl; }
	
};
class B{
	std::shared_ptr<A> b_ptr;
public:
	void set_B(std::shared_ptr<B> &b){
	
		a_ptr=a;
	}
	B() {cout<<"B constructor"<<endl; }
	
	~B() {cout<<"B constructor"<<endl; }
	
};

int main(){
	
	shared_ptr<A> a = make_shared<A>();
	shared_ptr<B> b=make_shared<B>();
	
	a->set_B(b);
	b->set_A(a);
	
	return 0;
}
//operator overloading


what is operator overloading 
copy and move semantics
Number result=multiply(add(a,b), divide(c,d));


using  overloaded operators

::
:?
.*
.
sizeof

Operator Overloading:

Inheritance:
The project in codelite: DerivingOurFirstClass

//Inheritance

Inheritance is A relationship
Composition has A relationship

Composition use much more frequent than inheritance

//composition
class Person{

private:
	std::string name; //has-a name
	Account account; //has-a account

}


class Base{

	//Base class members...

};


class Derived: access--specifier Base{
	//Derived class members

};

Access specifier : private , public , protected

public is-a relationship


private and protected has-a relationship


C++ derivation syntax:





class Account{


};


class Savings_Account: public Account{

	

};


//C++ creating objects

Account account {};
Account *p_account = new Account();


account.deposit(1000.0);
p_account->withdraw(200.0);

delete p_account;


Savings_Account sav_account {};
Savings_Account *p_sav_account = new Savings_Account();

sav_account.deposit(1000.0);
p_sav_account->withdraw(200.0);


delete p_sav_account;



#ifndef ACCOUNT

code for that:

#include <iostream>

using namespace std;

class Base
{
    // Note friends of Base has access to all
public:
    int a {0};
    void display() { std::cout << a <<"," << b << "," << c << endl; } // member method has access to all

protected:
    int b { 0 };

private:
    int c { 0 };
};

class Derived : public Base
{

    // a will be public
    // b will be protected
    // c will not be accessible
public:
    void access_base_members()
    {

        a = 100; // ok
        b = 200; // Ok
        // c=300; //not accessible
    }
};

int main()
{
    Base base1;
    base1.a = 100; // ok
    base1.b = 200; // compiler error
    base1.c = 300; // compiler error

    Derived d;
    d.a = 100; // Ok
    d.b = 200; // Error
    d.c = 300; // Error

    return 0;
}

Inherited Constructors and Destructors

//constructors and destructors

class Base{

public:
	Base(){ cout<<"Base Constructor"<<endl; }
};

class Derived: public Base{

public:
	Derived(){ cout<<"Derived Constructor"<<endl; }

};

//Constructor


Base base; //Base constructor

Derived derived; //Base constructor and Derived constructor have invoked 


//Destructors

//class destrcutors are invoked in the reverse order as constructor

//the derived one need to destroy first

class Base{

	public:
		Base(){cout<<"Base constructor"<<endl;}
		~Base(){cout<<"Base destructor"<<endl;}

};

class Derived: public Base{

	public:
		Derived(){cout<<"Derived constructor"<<endl;}
		~Derived(){cout<<"Derived destructor"<<endl;}
}



Base base; //base constructor, base destructor

Derived derived; //base constructor, derived constructor, derived destructor, base desttuctor

//Now seeing in the live code

Passing arguments to base class constructors:

#include<iostream>

using namespace std;

class Base{
private:
    int value;
    
public:
	Base(): value{0} { cout<<"Base no -args Constructor"<<endl; }
    Base(int x): value{x} {cout<<"Base(int) overloaded constructor"<<endl;}
    ~Base() {cout<<"Base destructor"<<endl;}
};

class Derived: public Base{
private:    
    int doubled_value;
public:
	Derived(): Base {}, doubled_value {0} { cout<<"Derived Constructor"<<endl; }
    Derived(int x): doubled_value{x*2} {cout<<"Derived(int) overloaded constructor"<<endl;}
    ~Derived() {cout<<"Derived constructor"<<endl;}
};

int main()
{
   // Base b;
   // Base b{100};
    Derived d {1000};
    return 0;
}

Copy/ Move constructors and operator with derived class:

Polymorphism:

//Fundamental to object orineted programming

//compile time == static binding
//run time == late-binding //dynamic binding


Polymorphism

Compile Time:
	-Function overloading
	-Operator overloading

Run-Time: //it is use in real life
	-Function overriding
	
A non-polymorphic example. Static binding //it is not good practic

void display_count(const Account &acc){ 
	acc.display();
	
}

Account a ;
display_account(a);

Savings b;
display_account(b);

Checking c;
display_account(c);

Trust d;
display_account(d);

Lambda Expressions:

//Stateless lambda expressions
[] () -> return_type specifiers {};
int x {10};


[] (int x ) {std::cout<<x;} (100);


const int n {3};
int nums n [10,20,30];
auto sum = [] (int nums [] , int n ){
	int sum {0};
	for (int i = 0; i<n; i++)
		sum+=nums[i];
	return sum;
};

std:.cout<<sum(nums,3);

//value parameter
[] (int x) {std::cout<<x;};
//reference parameter
[] (int &x) {std::cout<<x;};



int test_score1 {88};
int test_score2  {75};
 auto bonus = [] (int *score1, int *score2, int bonus_points){
	*score1+= bonus_points;
	*score += bonus_points;
 };
 
 
 bonus(&test_score1, &test_score2, 5);
 
 
 
std::cout<<"test_score1:"<<test_Score1<<std::endl;
std::cout<<"test_score2:"<<test_Score2<<std::endl;


std::vector <int> test_scores {93,88,75,68,65};

auto bonus = [] (std::vector<int> &scores, int bonus_points){

	for(int &score:scores)
		score+=bonus_points;
		

}



bonus(test_scores,5);


std::cout<<"test_scores:"<<std::endl;
std::cout<<"test_scores[0]<<std::endl;
std::cout<<"test_scores[1]<<std::endl;
std::cout<<"test_scores[2]<<std::endl;
It would be a great help, if you support by sharing :)
Author: zakilive

Leave a Reply

Your email address will not be published. Required fields are marked *