- Namespaces
- in_out
- Class_and_instance
- Member_attributes_and_member_functions
- This
- Initialization
- const
- Visibility
- Structs_vs_Class
- Getter
- Comparisons
- Non_Member_Attributes_and_functions
- Pointers_to_members_and_members_functions
- ex01 notes
- ex02 notes
In each scope, a name can only represent one entity. So, there cannot be two variables with the same name in the same scope. Using namespaces, we can create two variables or member functions having the same name.
Namespaces allow us to group named entities that otherwise would have global scope into narrower scopes, giving them namespace scope. This allows organizing the elements of programs into different logical scopes referred to by names.
- Namespace declarations appear only at global scope.
- Namespace declarations can be nested within another namespace.
- Namespace declarations don’t have access specifiers. (Public or private)
- No need to give semicolon after the closing brace of definition of namespace.
- We can split the definition of namespace over several units.
int my_var = 3;
int my_function(void) {return 3;}
namespace my_namespace {
int my_var = 5;
int my_function(void) {return 6;}
}
namespace alias = my_namespace;:: scope resolution operator
[namespace]::[var]
alias::my_varstd:: standart library namespace
::my_var == my_var
std::cout << "Hello, C++!" << std::endl; == write(1, "Hello, C++!\n", 15);
std::cin >> buffer; -> reads from stdin
std::cout << "you sayed:" << buffer << "!" << std::endl;
.class pre extension to better organize and makes class files explicit
My_class.class.hpp
My_class.class.cpp
constructors and distructors don´t have a return type, they are producers
#ifndef MY_CLASS_H
# define MY_CLASS_H
class My_class {
My_class(void); //Constructor - is called when the class is instaciated
~My_class(void); //Destructor - is called when the instance get destroyed
};
#endifconstructors can also accept parameters
class My_class {
My_class(char c, int i, float f); //Constructor - is called when the class is instaciated
~My_class(void); //Destructor - is called when the instance get destroyed
};
class is a static part, a model
the incante will be the dynamic part
the class is the molde and the instance is the cake
instanciating:
int main(void) {
My_class my_instance;
return(0);
}
member attribute a variable that you have in your class that you may use in a instance
member functions are functions that you can use in your instances
void Class_name::function_name(void) {
//function body
return ;
}
int main(void) {
Class_name my_instance;
my_instance.function_name();
return (0);
}this is a pointer to the current instance
We use this inside the constructor
My_class::My_class(void) {
this->my_var = 42;
this->my_func();
return ;
}class My_class {
char my_char;
int my_int;
float my_float;
My_class(char c, int i, float f); //Constructor - is called when the class is instaciated
~My_class(void); //Destructor - is called when the instance get destroyed
};
this:
My_class::My_class(char c, int i, float f) {
this->my_char = c;
this->my_int = i;
this->my_float = f;
return ;
}
with initialization list sintax became this:
My_class::My_class(char c, int i, float f) : my_char(c), my_int(i), my_float(f){
return ;
}
const cannot be changed
in c++ we can declare a const in our class and define a different value for each object in the constructor
class My_class {
public:
float const pi;
My_class(float const f);
~My_class(void);
}My_class::My_class(float const f) : pi(f) {
return ;
}It's also possible to use constante in a functions, meaning that the instance of the class cannot be changed in this function
class My_class {
public:
float const pi;
int i;
My_class(float const f);
~My_class(void);
void my_func(void) const; // read-only mode
}void My_class::my_func(void) const {
this->i = 0; //compiler error! We can't assign any value for our instance
return ;
}public and private control the encapsulation of the members of the class
public available outside the class
private only available inside the class
_my_private_var_
_my_private_function
_ before the name: convention for privates variables and functions
Expose outside only the parts will be usefull for the user Keep private as much as possible
Class and structs works in the same way in C++, but the scope of the structure is public by default and the scope of the class is private by the default
Proxy pattern is a software design pattern. A proxy, in its most general form, is a class functioning as an interface to something else.
get and set are getters functions, a interface to interact with a private variable
class My_class {
public:
My_class(void);
~My_class(void);
int get_var(void) const; //getter, read only mode
bool set_var(int value); //setter with bool return to indicates if the value has changed
private:
int _var;
}with the getters we get control over the class variables, returning a copy when needed and making rules to the setter
(...)
int My_class::get_var(void) const {
return this->_var;
}
bool My_class::set_var(int value) {
if (value >= 0)
{
this->_var = value;
return (true);
}
return (false);
}it's possible not only to compare adresses but also structural equality
in class header:
int compare(My_class *other) const;in class implementation:
int My_class::compare(My_class *other) const {
if (this->_var < other->get_var())
return (-1);
else if (this->_var > other->get_var())
return (1);
return (0);
}or Class attributes and functions (not-instances attributes and functions)
static: functions and variables from the class, and not for each instance
class My_class {
public:
My_class(void);
~My_class(void);
static int get_number_of_instances(void);
private:
static int _number_of_instances;
}
My_class::My_class(void) {
My_class::_number_of_instances += 1;
return ;
}
My_class::~My_class(void) {
My_class::_number_of_instances -= 1;
return ;
}
//static func dont have the instance as a secret argument, therefore we can't use THIS keyword
int My_class::get_number_of_instances(void) {
return My_class::_number_of_instances;
}
int My_class::_number_of_instances = 0; //initializing the static non-member variable
class My_class {
public:
int var;
My_class(void);
~My_class(void);
void func(void) const; //non-member function
}
int main(void) {
My_class instance;
My_class *instance_ptr;
int My_class::*ptr = NULL; //pointer to a int from My_class
void (My_class::*func_ptr)(void) const; //pointer to a non-member function from My_class
ptr = &My_class::var; //assigning the var address from My_class to the pointer, without specifiyng an instance
instance.*ptr = 21; //using the pointer to assign 21 to var from instance
instance_ptr->*ptr = 42; //using the pointer to the var and the pointer to the instance to assign 42 to var
func_ptr = &My_class::func; //assigning the func address to My_class-function-pointer
(instance.*func_ptr)(); //using the function pointer to call func from instance
(instance_ptr->*func_ptr)(); //using the function pointer and instance pointer to call func
return 0;
}
Why I choose a_string == other_string over a_string.compare(other_string):
std::string::compare() works pretty much like strcmp and returns 0 if the string are equal, < zero if a_string is less than other_string and > 0 if a_string is greater than other_string.
In the other hand, the equality operator only tests for equality and returns a bool. Hence I was not interested in how the strings are related, but in the equality between then, I choose == (it's also more straight forward and readable than !a_string(other_string) and still a huge improvement over C, beeing able to make this comparsion is such a simple way)
I have to options to ask the user for an input, and booth of them have some issues:
std::getline(std::cin, input) stores in the input string variable the hole string, until the user press enter. But this method stores the \n in the cin buffer, therefore when the getline is called again, it reads the \n and exits the function without the user have the chance to write anything.
In the other hand, std::cin >> input doesn't handle well spaces, only beeing able to store a word without any space.
To solve this problem, I used std::cin.ignore() function.
Extracts characters from the input sequence and discards them, until either n characters have been extracted, or one compares equal to delim.
The function also stops extracting characters if the end-of-file is reached. If this is reached prematurely (before either extracting n characters or finding delim), the function sets the eofbit flag.
It's a tricky function, though, cause in loops it can ignore the first letter of the words, so be carefull where you place it.
this and this other threads in stackoverflow give's a good overview of the issue.
initializing the four static non-member variable:
int Account::_nbAccounts = 0;
int Account::_totalAmount = 0;
int Account::_totalNbDeposits = 0;
int Account::_totalNbWithdrawals = 0;and member variables in the constructor
Account::Account( int initial_deposit ) : _amount(initial_deposit),
_accountIndex(_nbAccounts),//cause we initialize _nbAccount in 0 and keep track of this number in each instance created
_nbDeposits(0),
_nbWithdrawals(0)
{
Account::_nbAccounts++; //next instance index will be the next one
Account::_amount += this->_amount; // == initial_deposit
}Account::~Account( void )
{
Account::_nbAccounts--; //destructor needs to subtract the instance from the total accounts
Account::_amount -= this->_amount; //same with total amount from all accounts
}log clue: [19920104_091532] index:0;p_amount:47;withdrawal:refused
when the withdrawal is more than the value, it is refused
compiler clue: error: field '_amount' will be initialized after field '_accountIndex' [-Werror,-Wreorder-ctor]
log clue:
[19920104_091532] index:0;amount:42;created
[19920104_091532] index:1;amount:54;created
[19920104_091532] index:2;amount:957;created
[19920104_091532] index:3;amount:432;created
[19920104_091532] index:4;amount:1234;created
[19920104_091532] index:5;amount:0;created
[19920104_091532] index:6;amount:754;created
[19920104_091532] index:7;amount:16576;created
when each account (instance) is created, infos are logged (same when they are distroyed) the values match with amount array
log clue:
[19920104_091532] accounts:8;total:20049;deposits:0;withdrawals:0
[19920104_091532] index:0;amount:42;deposits:0;withdrawals:0
[19920104_091532] index:1;amount:54;deposits:0;withdrawals:0
[19920104_091532] index:2;amount:957;deposits:0;withdrawals:0
[19920104_091532] index:3;amount:432;deposits:0;withdrawals:0
[19920104_091532] index:4;amount:1234;deposits:0;withdrawals:0
[19920104_091532] index:5;amount:0;deposits:0;withdrawals:0
[19920104_091532] index:6;amount:754;deposits:0;withdrawals:0
[19920104_091532] index:7;amount:16576;deposits:0;withdrawals:0
between created and deposits, display account general infos and each account info, hence the display account function also displays each account informations
Account info are displayed in displayStatus function inside std::for_each loop =D
In order to solve the mistery, I inserted some printf's in key lines of the code, it was very enlightening!