-
Notifications
You must be signed in to change notification settings - Fork 0
Module00
- Namespaces
- Streams
- Class & Instance
- Member Attributes & Functions
- non-member Attributes & Functions
- This Pointer
- Initialization List
- Const
- getters
- class vs struct
-
namespaces provides a method for preventing name conflicts in large projects. It allows you to group symbols that are related together
-
All the entities included in the
C++ standard libraryare included in thestdnamespace -
However,
using namespace stdis considered bad practice, as it imports the entirety of thestdnamespace into the current namespace of the program. It's better to use scope resolution operator to access the specific entity (likestd::cout)
int gl_var = 1;
int f(void) {return 2;}
namespace Foo {
int gl_var = 3;
int f(void) {return 4;}
}
namespace Bar {
int gl_var = 5;
int f(void) {return 6;}
}
// use namespace aliasing to keep a shorter and more expressive syntax
// :: scope resolution operator
namespace Muf = Bar;
int main(void){
printf("gl_var: [%d]\n", gl_var);
printf("f(): [%d]\n\n", f());
//exactly the same as above (global scope)
printf("::gl_var: [%d]\n", ::gl_var);
printf("::f(): [%d]\n\n", ::f());
printf("Foo::gl_var: [%d]\n", Foo::gl_var);
printf("Foo::f(): [%d]\n\n", Foo::f());
printf("Bar::gl_var: [%d]\n", Bar::gl_var);
printf("Bar::f(): [%d]\n\n", Bar::f());
printf("Muf::gl_var: [%d]\n", Muf::gl_var);
printf("Muf::f(): [%d]\n\n", Muf::f());
return (0);
}
Output
gl_var: [1]
f(): [2]
::gl_var: [1]
::f(): [2]
Foo::gl_var: [3]
Foo::f(): [4]
Bar::gl_var: [5]
Bar::f(): [6]
Muf::gl_var: [5]
Muf::f(): [6]-
Streams acts as an intermediaries between the programs and the actual IO devices. It frees the programmers from handling the actual devices
-
<<>>redirects the flow to or from a stream (likestd::coutorstd::cin) -
Object
std::endlhandles newline character on different OS
#include <iostream>
int main(void)
{
char buff[512];
std::cout << "Hello World!" << std::endl;
std::cout << "Input a word: ";
std::cin >> buff;
std::cout << "You entered: [" << buff << "]" << std::endl;
return 0;
}
Output
Hello World!
Input a word: xx
You entered: [xx]-
C++ is an object-oriented programming language. An object is created from a class. Everything in C++ is associated with classes and objects, along with its attributes(
variables) and methods(functions) -
A class is a user-defined data type. It works as an object constructor, or a blueprint for creating objects. A class is
staticand it's a model which objects are built on. Instance is the dynamic part and it's aninstantiationof a class
-
Constructorsanddestructorsare special member functions of classes that are used to construct and destroy class objects.-
Constructormay involve memory allocation and initialization for objects.Destructormay involve cleanup and deallocation of memory for objects - Like other member functions, constructors and destructors are declared within a class declaration. They can be defined inline or external to the class declaration
-
Constructoranddestructordon't have a return type - The compiler
automaticallycalls constructors when defining class objects and calls destructors when class objects go out of scope.
-
An example of Class
- Sample.class.hpp
#ifndef SAMPLE_CLASS_H
# define SAMPLE_CLASS_H
class Sample
{
public:
Sample(void); // CPP use the name of the class for constructor
~Sample(void); // and the name of the class for destructor
}; // don't forget to end with semicolon
#endif- Sample.class.cpp
#include <iostream>
#include "Sample.class.hpp"
Sample::Sample(void)
{
std::cout << "Constructor called" << std::endl;
return ;
}
Sample::~Sample(void)
{
std::cout << "Destructor called" << std::endl;
return ;
}- main.cpp
#include "Sample.class.hpp"
int main(void)
{
// the line below instantiate an instance
// code in constructor will also run (to initialise data for instance)
Sample instance;
return (0);
// destructor is called when the instance goes out of scope
}Output
Constructor called
Destructor called-
A member function of a class is a function that has its definition or its prototype within the class definition like any other variable. It operates on any object of the class of which it is a member, and has access to all the members of a class for that object.
-
Member attribute is a variable you have in your class, and you may use from an instance.
An example of class and member functions (source link)
-
Memberattributes / functions are present inside of a class. It means that the class needs to be instantiated, in order to use this attribute / function. Each attribute will be different in each instance -
Non membervariables and functions exist at the class level, and not at the instance level -
Another terminology:
-
Instancevariables / functions refers tomemberattributes / functions -
Classvariables / functions refers tonon memberattributes / functions
-
An algorithm on whether to choose member function or non member function, created by Scott Meyers (source link)
if (f needs to be virtual)
make f a member function of C;
else if (f is operator>> or operator<<)
{
make f a non-member function;
if (f needs access to non-public members of C)
make f a friend of C;
}
else if (f needs type conversions on its left-most argument)
{
make f a non-member function;
if (f needs access to non-public members of C)
make f a friend of C;
}
else if (f can be implemented via C public interface)
make f a non-member function;
else
make f a member function of C;Example of non member attributes / functions
- Sample.class.hpp
#ifndef SAMPLE_CLASS_H
# define SAMPLE_CLASS_H
class Sample {
public:
Sample(void);
~Sample(void);
// non member function
// when the function does not have anything to do with the other class
// functions, but you want it to be part of the class
static int getNbInst(void);
private:
// non member attribute
// number of instances: this information only makes sense at the class level
static int _nbInst;
};
#endif- Sample.class.cpp
#include <iostream>
#include "Sample.class.hpp"
Sample::Sample(void)
{
std::cout << "Constructor called" << std::endl;
Sample::_nbInst += 1;
return;
}
Sample::~Sample(void)
{
std::cout << "Destructor called" << std::endl;
Sample::_nbInst -= 1;
return;
}
// With member function, CPP will pass as a parameter, an instance of your class
// so this-> can be used
// this pointer is not passed for a non member function, so you can't
// use this-> here
int Sample::getNbInst(void)
{
return Sample::_nbInst;
}
// this is the only way to initialise a non member attribute (static attribute)
// this is initialised without an instance being created
int Sample::_nbInst = 0;- main.cpp
#include <iostream>
#include "Sample.class.hpp"
void f0(void)
{
Sample instance;
std::cout << "Number of instances = " << instance.getNbInst() << std::endl;
return;
}
void f1(void)
{
Sample instance;
std::cout << "Number of instances = " << instance.getNbInst() << std::endl;
f0();
return;
}
int main(void)
{
std::cout << "Number of instances = " << Sample::getNbInst() << std::endl;
f1();
std::cout << "Number of instances = " << Sample::getNbInst() << std::endl;
return 0;
}Output
Number of instances = 0
Constructor called
Number of instances = 1
Constructor called
Number of instances = 2
Destructor called
Destructor called
Number of instances = 0-
In C++, each object gets its own copy of data members and all objects share a single copy of member functions. To refer to your current instance, use the special instance pointer
this. -
One member function only has one copy and is used by multiple objects, how are the proper data members accessed and updated? The compiler supplies an implicit pointer along with the names of the functions as 'this'
Example of member attributes, functions & this pointer
- Sample.class.hpp
#ifndef SAMPLE_CLASS_H
# define SAMPLE_CLASS_H
class Sample
{
public:
int foo;
Sample(void);
~Sample(void);
void bar(void);
};
#endif- Sample.class.cpp
#include <iostream>
#include "Sample.class.hpp"
Sample::Sample(void)
{
std::cout << "Constructor called" << std::endl;
this->foo = 42;
std::cout << "this->foo: " << this->foo << std::endl;
// it is possible to call a function from an instance pointer
this->bar();
return;
}
Sample::~Sample(void)
{
std::cout << "Destructor called" << std::endl;
return;
}
void Sample::bar(void)
{
std::cout << "Member function bar called" << std::endl;
return;
}- main.cpp
#include <iostream>
#include "Sample.class.hpp"
int main(void)
{
Sample instance;
return (0);
}Output
Constructor called
this->foo: 42
Member function bar called
Destructor called- Initialization list is used in initializing the data members of a class. The list of members to be initialized is indicated with constructor as a
comma-separated listfollowed by a colon
Example of initialization list
- Sample.class.hpp
#ifndef SAMPLE_CLASS_H
# define SAMPLE_CLASS_H
class Sample {
public:
//attributes
char a1;
int a2;
float a3;
Sample(char p1, int p2, float p3);
~Sample(void);
};
#endif- Sample.class.cpp
#include <iostream>
#include "Sample.class.hpp"
//initialise the attributes in a class
Sample::Sample(char p1, int p2, float p3) : a1(p1), a2(p2), a3(p3)
{
std::cout << "Constructor called" << std::endl;
std::cout << "this->a1 = " << this->a1 << std::endl;
std::cout << "this->a2 = " << this->a2 << std::endl;
std::cout << "this->a3 = " << this->a3 << std::endl;
}
Sample::~Sample(void) {
std::cout << "Destructor called" << std::endl;
return;
}- main.cpp
#include <iostream>
#include "Sample.class.hpp"
int main(void)
{
Sample instance('a', 42, 4.2f);
return (0);
}Output
Constructor called
this->a1 = a
this->a2 = 42
this->a3 = 4.2
Destructor called-
Variables declared with
constadded become constants and cannot be altered by the program -
const data membersmust be initialized usinginitialization list. No memory is allocated separately for const data member. It is folded in the symbol table due to which we need to initialize it -
const data membersis also a copy constructor. We don't need to call the assignment operator which means we are avoiding one extra operation -
The more your code is
constandread only, the more your code will be robust in the long term
Example of const
- Sample.class.hpp
#ifndef SAMPLE_CLASS_H
# define SAMPLE_CLASS_H
class Sample
{
public:
float const pi;
int qd;
Sample(float const f);
~Sample(void);
// const between ) & ; -> the instance of the class will never be altered
void bar(void) const;
};
#endif- Sample.class.cpp
#include <iostream>
#include "Sample.class.hpp"
// it's not assigning f value to pi attribute
// it's initialising pi attribute to the f value
Sample::Sample(float const f) : pi(f), qd(42) {
std::cout << "Constructor called" << std::endl;
return;
}
Sample::~Sample(void) {
std::cout << "Destructor called" << std::endl;
return;
}
// this is central to CPP
// define const when your member function should never be changed in the \
// current instance of your class
void Sample::bar(void) const {
std::cout << "this->pi = " << this->pi << std::endl;
std::cout << "this->qd = " << this->qd << std::endl;
// this assignment below won't work, as it's a const function
// this->qd = 0;
return;
}- main.cpp
#include <iostream>
#include "Sample.class.hpp"
int main() {
Sample instance(3.14f);
instance.bar();
return (0);
}Output
this->pi = 3.14
this->qd = 42
Destructor called- An accessor is a member function that allows someone to retrieve the contents of a protected data member
- The accessor must have the
same typeas the returned variable - The accessor does not need to have arguments
- A
naming conventionmust exist, and the name of the accessor must begin with thegetprefix
- The accessor must have the
-
In practice, all attributes of a class are private. Getters are the interface between the user and private attributes, to be sure that the values are always correct.
-
They usually have the prefix of
getandset. Getter can only access in the read-only mode and won't alter the content of the class. It allows you to have some control over what to give to the user. It also sets control to the user's input and make sure that they make sense
Example of getter
- Sample.class.hpp
#ifndef SAMPLE_CLASS_H
# define SAMPLE_CLASS_H
class Sample
{
public:
Sample(void);
~Sample(void);
int getFoo(void) const;
void setFoo(int v);
private:
int _foo;
};
#endif- Sample.class.cpp
#include <iostream>
#include "Sample.class.hpp"
Sample::Sample(void)
{
std::cout << "Constructor called" << std::endl;
this->setFoo(0);
std::cout << "this->getFoo() = " << this->getFoo() << std::endl;
return;
}
Sample::~Sample(void)
{
std::cout << "Destructor called" << std::endl;
return;
}
// grant only read-only access to the attribute
int Sample::getFoo(void) const
{
// return a copy of the _foo attribute
return this->_foo;
}
// this way allows the user to change the _foo attribute
void Sample::setFoo(int v)
{
// don't allow _foo to have a negative value
if (v >= 0)
this->_foo = v;
return;
}- main.cpp
#include <iostream>
#include "Sample.class.hpp"
int main(void)
{
Sample instance;
instance.setFoo(42);
std::cout << "instance.getFoo() = " << instance.getFoo() << std::endl;
instance.setFoo(-42);
std::cout << "instance.getFoo() = " << instance.getFoo() << std::endl;
return (0);
}Output
Constructor called
this->getFoo() = 0
instance.getFoo() = 42
instance.getFoo() = 42
Destructor called-
A class can also contain functions (called
methodsin C++). The member attributes and methods are hidden from the outside world, unless their declaration follows a public label -
Special methods (
constructoranddestructor) in C++. They run automatically when an object (an instance of the class) is created and destroyed -
Operators to work on the new data type can be defined using special methods (
member functions) -
One class can be used as the basis for the definition of another (
inheritance) -
Declaring a variable of the new type (an object) requires just the name of the class. The keyword
classis not required -
structandclasswork almost the same way in C++. The difference is that the default accessibility / scope of member variables and methods isprivatein a class, while it'spublicin a struct. The use ofclassis generally preferred