2026-04-20 (3VO): C++ Intro#
From Data Encapsulation:
Spickzettel#
Original C#
#include <stdio.h>
#include <math.h>
struct point
{
float x;
float y;
};
void point_move(struct point* p, float x, float y)
{
p->x += x;
p->y += y;
}
float point_abs(const struct point* p)
{
return sqrtf(p->x*p->x + p->y*p->y);
}
int main(void)
{
struct point p;
printf("point (%f,%f)\n", p.x, p.y);
printf("abs %f\n", point_abs(&p));
return 0;
}
Constructor#
Don’t leave anything uninitialized
this? Currently only used to disambiguate between two versions ofx.
#include <stdio.h>
#include <math.h>
struct point
{
point(float x, float y)
{
this->x = x;
this->y = y;
}
float x;
float y;
};
int main(void)
{
point p(3,4);
printf("point (%f,%f)\n", p.x, p.y);
return 0;
}
Default Constructor#
People want
point p;to have a defined outcome|longrightarrow| default constructor
#include <stdio.h>
#include <math.h>
struct point
{
public:
point()
{
this->_x = 0;
this->_y = 0;
}
point(float x, float y)
{
this->_x = x;
this->_y = y;
}
float x() const { return this->_x; }
float y() const { return this->_y; }
void move(float x, float y)
{
this->_x += x;
this->_y += y;
}
float abs() const
{
return sqrtf(this->_x*this->_x + this->_y*this->_y);
}
private:
float _x;
float _y;
};
int main(void)
{
point p; // <-- default initialization
printf("point (%f,%f)\n", p.x(), p.y());
printf("abs %f\n", p.abs());
return 0;
}
Non const Method: move()#
move()modifies apointExplicit first parameter becomes implicit
this
#include <stdio.h>
#include <math.h>
struct point
{
point(float x, float y)
{
this->x = x;
this->y = y;
}
void move(float x, float y)
{
this->x += x;
this->y += y;
}
float x;
float y;
};
int main(void)
{
point p(3,4);
printf("point (%f,%f)\n", p.x, p.y);
p.move(1,1);
printf("point (%f,%f)\n", p.x, p.y);
return 0;
}
const Method: abs()#
Does not modify a point
|longrightarrow|
constmethod
#include <stdio.h>
#include <math.h>
struct point
{
point(float x, float y)
{
this->x = x;
this->y = y;
}
void move(float x, float y)
{
this->x += x;
this->y += y;
}
float abs() const
{
return sqrtf(this->x*this->x + this->y*this->y);
}
float x;
float y;
};
int main(void)
{
point p(3,4);
printf("point (%f,%f)\n", p.x, p.y);
printf("abs %f\n", p.abs());
return 0;
}
Access Specifiers: public And private#
Use case: nobody should be able to fiddle with members x and y
in an uncontrolled way!
A class definition may have access specifiers:
public: members visible to outside (default forstruct)protected: members visible to derived classes |longrightarrow| a sign of implementation inheritance (discouraged)private: members only visible to other members of same class (default forclass) |longrightarrow| access methodsLet’s remove the explicit
this, btw.
#include <stdio.h>
#include <math.h>
class Point
{
public:
Point(float x, float y)
{
_x = x;
_y = y;
}
float x() const { return _x; }
float y() const { return _y; }
void move(float x, float y)
{
_x += x;
_y += y;
}
float abs() const
{
return sqrtf(_x*_x + _y*_y);
}
private:
float _x;
float _y;
};
int main(void)
{
Point p(3,4);
printf("point (%f,%f)\n", p.x(), p.y());
printf("abs %f\n", p.abs());
return 0;
}
Separate Compilation Units#
Class definition may contain method implementations
Expanded inline when called (entire code copied to caller)
Not space friendly for large methods
|longrightarrow| Put into separate compilation unit and generate a real call
#include "point.h"
#include <stdio.h>
int main(void)
{
const Point p(3,4);
printf("point (%f,%f)\n", p.x(), p.y());
printf("abs %f\n", p.abs());
return 0;
}
#pragma once
class Point
{
public:
Point(float x, float y)
{
_x = x;
_y = y;
}
float x() const { return _x; }
float y() const { return _y; }
void move(float x, float y);
float abs() const;
private:
float _x;
float _y;
};
#include "point.h"
#include <math.h>
void Point::move(float x, float y)
{
this->_x += x;
this->_y += y;
}
float Point::abs() const
{
return sqrtf(this->_x*this->_x + this->_y*this->_y);
}