-
Notifications
You must be signed in to change notification settings - Fork 3
module01
-
malloc()
an object does not work in C++, because it does not call the constructor of the object. Similarly, if youfree()
an object, it also won't call the destructor -
new()
anddelete()
usemalloc()
andfree()
in reality, but they also call the constructor and destructor in an appropriate way -
new()
does not take parameters. So need to think of ways to initialise values
Example 1: Initialise a variable on the stack and heap
#include <string>
#include <iostream>
class Student
{
private:
std::string _login;
public:
Student(std::string login) :_login(login)
{
std::cout << "Student " << this->_login << " is born" << std::endl;
}
~Student()
{
std::cout << "Student " << this->_login << " died" << std::endl;
}
};
int main()
{
Student bob = Student("bfubar");
Student* jim = new Student("jfubar");
// Do some stuff here
delete jim; // jim is destroyed
return (0); // bob is destroyed
}
Result
Student bfubar is born
Student jfubar is born
Student jfubar died
Student bfubar died
Example 2: Initialise an array of classes
#include <string>
#include <iostream>
class Student
{
private:
std::string _login;
public:
Student() :_login("ldefault")
{
std::cout << "Student " << this->_login << " is born" << std::endl;
}
~Student()
{
std::cout << "Student " << this->_login << " died" << std::endl;
}
};
int main()
{
Student* students = new Student[5]; // new() does not take parameters
// Do some stuff here
delete [] students;
return (0);
}
Result
Student ldefault is born
Student ldefault is born
Student ldefault is born
Student ldefault is born
Student ldefault is born
Student ldefault died
Student ldefault died
Student ldefault died
Student ldefault died
Student ldefault died
-
References are aliases for existing variables. It is a pointer that is
constant
and alwaysdereferenced
andnever void
-
References vs. pointer
- You can't change where the reference is pointing to. It will always point to the same variable
- You can't create a reference and let it point to nothing (uninitialised reference). Because it is constant, you can't point to something else later. But a reference can't point to nothing
- Advantage: when you have a reference, you are sure that it's pointing to something
- Reference is like a dereferenced pointer. So you don't need to add any symbol to access it
-
References are complimentary to pointers but they don't replace pointers. However, you can't have a reference and not initialise it to something. In comparison, using a pointer, you can point it to something that does not exist in the beginning, and change what it points to later
-
Pointers are more flexible than references. If something should always exist and never change, use a references. But if it should not always exist and can change, use a pointer
Example: Simple usage of reference vs. pointer
#include <iostream>
int main()
{
int numberOfBalls = 42;
int* ballsPtr = &numberOfBalls;
int& ballsRef = numberOfBalls;
// the reference will be pointing to the variable
// from this point on, you can't change what your reference is pointing to
std::cout << numberOfBalls << " " << *ballsPtr << " " << ballsRef << std::endl;
*ballsPtr = 21;
std::cout << numberOfBalls << std::endl;
ballsRef = 84;
std::cout << numberOfBalls << std::endl;
return (0);
}
result
42 42 42
21
84
- Passing parameters by reference
Example
#include <iostream>
#include <string>
void byPtr(std::string* str)
{
*str += " and ponies";
}
void byConstPtr(std::string const * str)
{
std::cout << *str << std::endl;
}
void byRef(std::string& str)
{
str += " and ponies";
}
void byConstRef(std::string const & str)
{
std::cout << str << std::endl;
}
int main()
{
std::string str = "i like butterflies";
std::cout << str << std::endl;
byPtr(&str);
byConstPtr(&str);
str = "i like otters";
std::cout << str << std::endl;
byRef(str);
byConstRef(str);
return (0);
}
Result
i like butterflies
i like butterflies and ponies
i like otters
i like otters and ponies
Example: const reference and pointer
#include <iostream>
#include <string>
class Student
{
private:
std::string _login;
public:
Student(std::string const & login) : _login(login)
{
}
std::string& getLoginRef()
{
return this->_login;
}
std::string const & getLoginRefConst() const
{
return this->_login;
}
std::string* getLoginPtr()
{
return &(this->_login);
}
std::string const * getLoginPtrConst() const
{
return &(this->_login);
}
};
int main()
{
Student bob = Student("bfubar");
Student const jim = Student("jfubar");
// use a const function on a non-const variable is not a problem
std::cout << bob.getLoginRefConst() << " " << jim.getLoginRefConst() << std::endl;
std::cout << *(bob.getLoginPtrConst()) << " " << *(jim.getLoginPtrConst()) << std::endl;
bob.getLoginRef() = "bobfubar";
std::cout << bob.getLoginRefConst() << std::endl;
*(bob.getLoginPtr()) = "bobbyfubar";
std::cout << bob.getLoginRefConst() << std::endl;
return (0);
}
Result
bfubar jfubar
bfubar jfubar
bobfubar
bobbyfubar
-
Streams that interact with files
-
There are different ways to read from an input file stream (ifstream)
- ifs.open();
- strings > float directly from the buffer, line by line (need to understand more)
-
There are also different types of streams, such as:
- string streams
- i string streams
- o string streams
Example
#include <iostream>
#include <fstream>
int main()
{
//ifstream: input file stream
std::ifstream ifs("numbers");
unsigned int dst;
unsigned int dst2;
ifs >> dst >> dst2;
std::cout << dst << " " << dst2 << std::endl;
ifs.close();
//-------------------------
//ofstream: output file stream
std::ofstream ofs("test.out");
ofs << "i like ponies a whole damn lot" << std::endl;
ofs.close();
return (0);
}
Result
# these come from the numbers from the numbers file
8 5
$ cat test.out
i like ponies a whole damn lot