Kapitel 9
Alle Codedateien dieses Kapitels herunterladen
09_1_1_Sizeof.cpp
#include <iostream>
#include <string>
struct Example
{
int a = 11;
int b = 21;
};
struct Example2
{
int a = 0;
int b = 0;
std::string c;
};
int main()
{
// sizeof() gibt die Größe im Speicher an.
// Allerdings hat diese Funktion so ihre Fallstricke.
// Sollten Sie sie in eigenem Code verwenden, empfehle
// ich Ihnen zwei Dinge:
// 1) Nochmals überlegen, ob Sie sie WIRKLICH brauchen
// 2) Weiteres Wissen im Internet anlesen
std::cout << sizeof(int) << std::endl;
std::cout << sizeof(char*) << std::endl;
std::cout << sizeof(std::string) << std::endl;
std::cout << sizeof(Example) << std::endl;
std::cout << sizeof(Example2) << std::endl;
std::cout << sizeof(std::string*) << std::endl;
return 0;
}
09_2_1_Beispielzeiger.cpp
#include <iostream>
int main()
{
int number = 256;
int* pointer = new int(42);
int* pointerToNumber = &number;
std::cout << "number: " << number << std::endl
<< "pointer: " << pointer << std::endl
<< "pointerToNumber: " << pointerToNumber << std::endl;
return 0;
}
// Hinweis: Dieses Programm enthält ein Memory-Leak,
// welches erst auf einer der nächsten Buchseiten
// behoben wird!
09_2_2_BeispielzeigerDereferenziert.cpp
#include <iostream>
int main()
{
int number = 256;
int* pointer = new int(42);
int* pTN = &number; // Abkürzung für: pointerToNumber
int* pTN2 = &number;
int* pointerToNull = nullptr;
std::cout << "Name | Adresse | Wert\n"
<< "--------------------------------\n"
<< "pointer |" << pointer << "|" << *pointer << "\n"
<< "pTN |" << pTN << "|" << *pTN << "\n"
<< "pTN2 |" << pTN2 << "|" << *pTN2 << "\n\n";
// Änderung des Wertes
number = 177;
std::cout << "Name | Adresse | Wert\n"
<< "--------------------------------\n"
<< "pointer |" << pointer << "|" << *pointer << "\n"
<< "pTN |" << pTN << "|" << *pTN << "\n"
<< "pTN2 |" << pTN2 << "|" << *pTN2 << "\n";
return 0;
}
// Hinweis: Dieses Programm enthält ein Memory-Leak,
// welches erst auf einer der nächsten Buchseiten
// behoben wird!
09_2_3_PointerToNull.cpp
#include <iostream>
int main()
{
int* pointerToNull = nullptr;
if (pointerToNull == nullptr)
{
std::cout << "Nullptr: " << pointerToNull << std::endl;
}
else
{
std::cout << *pointerToNull << std::endl;
}
return 0;
}
09_2_4_PfeilOperator.cpp
#include <iostream>
#include <string>
int main()
{
std::string* stringPointer = new std::string("Hello");
std::cout << stringPointer->size() << std::endl;
for (char c : *stringPointer)
{
std::cout << c;
}
std::cout << std::endl;
for (int i = 0; i < stringPointer->size(); i++)
{
std::cout << stringPointer->at(i);
}
return 0;
}
// Hinweis: Dieses Programm enthält ein Memory-Leak,
// welches erst auf einer der nächsten Buchseiten
// behoben wird!
09_2_5_SpeicherFreigeben.cpp
#include <iostream>
int main()
{
int* pointer = new int(42);
std::cout << *pointer << std::endl;
delete pointer;
// Ein Dereferenzieren nach einem delete würde zu einem
// Crash führen!
// std::cout << *pointer << std::endl;
return 0;
}
09_2_6_Zombievariable.cpp
#include <iostream>
int main()
{
int* pointerToNumber = nullptr;
if (true)
{
int number = 17;
pointerToNumber = &number;
}
// Das kann schwerwiegende Folgen haben:
std::cout << *pointerToNumber << std::endl;
return 0;
}
09_3_SmartPointer.cpp
#include <iostream>
#include <memory> // Für den Typ des Smart Pointers
int main()
{
std::shared_ptr<int> pointer = std::make_shared<int>(4);
std::cout << "1: *pointer " << *pointer << std::endl;
// Ohne Angabe sind Smart Pointer AUTOMATISCH nullptr
std::shared_ptr<int> pointer2;
// Ausgabe der Adresse: (Dereferenzieren würde crashen!)
std::cout << "2: pointer2 " << pointer2 << std::endl;
if (true)
{
std::shared_ptr<int> pointer3;
pointer3 = std::make_shared<int>(35);
pointer2 = pointer3;
std::cout << "3: *pointer2 " << *pointer2 << std::endl;
// Wie bei normalen Zeigern auch ändert sich der
// Wert bei allen, die auf denselben Speicher zeigen
*pointer3 = 11;
std::cout << "4: *pointer2 " << *pointer2 << std::endl;
}
// pointer3 verlässt den Gültigkeitsbereich, aber pointer2
// hat immer noch Zugriff auf den gemeinsamen Speicher.
std::cout << "5: *pointer2 " << *pointer2 << std::endl;
// Das Prüfen auf nullptr geht genauso wie bei Zeigern:
if (pointer2 != nullptr)
{
std::cout << "6: pointer2 ist nicht Null" << std::endl;
}
return 0;
}
// Nach Ende des Programms wurden pointer und
// pointer2 automatisch aufgeräumt
09_4_1_DurchNullTeilen.cpp
#include <iostream>
#include <exception>
double divide(int a, int b)
{
if (b == 0)
{
throw std::exception("Nenner ist null");
}
return a / static_cast<double>(b);
}
int main()
{
std::cout << divide(10, 3) << std::endl;
std::cout << divide(10, 0) << std::endl;
return 0;
}
09_4_2_FehlerAbfangen.cpp
#include <iostream>
#include <exception>
double divide(int a, int b)
{
if (b == 0)
{
throw std::exception("Nenner ist null");
}
return a / static_cast<double>(b);
}
int main()
{
std::cout << divide(10, 3) << std::endl;
try
{
std::cout << divide(10, 0) << std::endl;
std::cout << "Kein Fehler aufgetreten!" << std::endl;
}
catch (std::exception& ex)
{
std::cerr << "Fehler abgefangen: " << ex.what() << std::endl;
}
std::cout << "Programmende" << std::endl;
return 0;
}
09_4_3_StoiFehler.cpp
#include <iostream>
#include <exception>
#include <string>
int main()
{
std::cout << std::stoi("123") << std::endl;
try
{
std::cout << std::stoi("abc") << std::endl;
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
09_5_1_Aufteilung
Aufteilung.cpp
#include <iostream>
#include "Aufteilung.h"
int sum(int a, int b)
{
return a + b;
}
Person::Person(std::string name)
: name(name)
{
}
void Person::printName()
{
std::cout << "Name: " << name << std::endl;
}
int main()
{
std::cout << "1+2 = " << sum(1, 2) << std::endl;
Person hans("Hans Wurst");
hans.printName();
return 0;
}
/*
class Person
{
public:
Person(std::string name)
: name(name)
{
}
void printName()
{
std::cout << "Name: "
<< name << std::endl;
}
private:
const std::string name;
};
*/
Aufteilung.h
#pragma once
#include <string>
int sum(int a, int b);
class Person
{
public:
Person(std::string name);
void printName();
private:
const std::string name;
};
09_5_2_Beispielfabrik
Beispielfabrik.cpp
#include "Robot.h"
#include "Factory.h"
int main()
{
Factory factory;
factory.addRobot(Robot("WALL-E"));
factory.addRobot(Robot("R2-D2"));
factory.startWork();
return 0;
}
Factory.cpp
#include "Factory.h"
void Factory::addRobot(const Robot& robot)
{
robots.push_back(robot);
}
void Factory::startWork()
{
for (Robot& robot : robots)
{
robot.work();
}
}
Factory.h
#pragma once
#include <vector>
#include "Robot.h"
class Factory
{
public:
void addRobot(const Robot& robot);
void startWork();
private:
std::vector<Robot> robots;
};
Robot.cpp
#include "Robot.h"
#include <iostream>
Robot::Robot(const std::string& name) : name(name)
{
}
void Robot::work()
{
std::cout << name << ": Arbeit, Arbeit!" << std::endl;
}
Robot.h
#pragma once
#include <string>
class Robot
{
public:
Robot(const std::string& name);
void work();
private:
const std::string name;
};