Project 11.15 Section 11 ⚡ Embedded Relevance: High friend Encapsulation Hardware Drivers HAL

11.15 Controlled Access to Private Hardware Drivers

Executive Summary: Understanding the friend keyword to grant privileged internal access to helper classes without exposing raw registers globally.

💻 1. Annotated Source Code

#ifndef RECTANGLE_H
#define RECTANGLE_H

class Rectangle {
	friend void changeData(Rectangle& rect);
	friend void printData(Rectangle& rect);

	friend class RectangleHelper;

	public:
		Rectangle();
		Rectangle(double length, double width);
		double getLength() const;
		double getWidth() const;
		void setLength(double length);
		void setWidth(double width);
		double area() const;
		double perimeter() const;

	private:
		double length; 
		double width;
};

#endif 
#include "Rectangle.h"

Rectangle::Rectangle() {
	length = 1;
	width = 1;
}

Rectangle::Rectangle(double length, double width) {
	this->length = length;
	this->width = width;
}

double Rectangle::getLength() const {
	return length;
}

double Rectangle::getWidth() const {
	return width;
}

void Rectangle::setLength(double length) {
	this->length = length;
}

void Rectangle::setWidth(double width) {
	this->width = width;
}

double Rectangle::area() const {
	return length * width;
}

double Rectangle::perimeter() const {
	return 2 * (length + width);
}
#ifndef RECTANGLE_HELPER_H
#define RECTANGLE_HELPER_H

#include "Rectangle.h"

class RectangleHelper {
	public:
		void modifyRectangle(Rectangle& rect) {
			rect.length = 500;
			rect.width = 500;
		}
};

#endif 
#include <iostream>
#include "Rectangle.h"
#include "RectangleHelper.h"

using namespace std;

void changeData(Rectangle& rect);
void printData(Rectangle& rect);

int main() {
	Rectangle r1(10, 25);
	RectangleHelper helper;

	cout << "r1 area: " << r1.area() << endl;

	changeData(r1);

	cout << "Now, r1 area: " << r1.area() << endl;

	helper.modifyRectangle(r1);
	cout << "after helper modifies, area: " << r1.area() << endl;

	cout << "printing data directly with printData:" << endl;
	printData(r1);

	return 0;
}

void changeData(Rectangle& rect) {
	rect.length = 100;
	rect.width = 100;
}

void printData(Rectangle& rect) {
	cout << "length: " << rect.length
		<< ", width: " << rect.width << endl;
}

📐 2. Architecture & UML Class Model

📐 Friend Classes & Private Encapsulation Bypass Mechanics
+ Public - Private # Protected
<<class>> Rectangle Encapsulated Entity
-length : double
-width : double
+Rectangle(l: double, w: double)
+friend class RectangleHelper
<<class>> RectangleHelper Friend Utility
(none / stateless)
+modifyDimensions(r: Rectangle&, l: double, w: double) : void[Direct Private Access]
+printDiagnostics(r: const Rectangle&) : void
🔗 Architectural Relationships & Hierarchy
RectangleHelper ─ ─ > granted friend access to private fields ─ ─ > Rectangle

📚 3. Core C++ Concepts Deep-Dive

Friendship in C++

friend declarations grant external functions or classes access to private/protected members.

⚡ 4. Embedded Systems & Hardware Reality

HAL & Driver Cohesion

A hardware Peripheral class can grant friend access to a Diagnostic Manager without making low-level configuration registers public.

💡 5. Production-Ready Embedded Refactoring

💡 Production-Ready Refactor
class UartDriver {
    friend class UartDiagnostics;
private:
    uint32_t errorCount_ = 0;
};

📝 Knowledge Verification Quiz

Test your understanding of the C++ concepts and embedded microcontroller trade-offs covered in this guide. Click any option for instant feedback.

Q1. Is friendship in C++ inherited or transitive?
A Yes, derived classes inherit friends automatically.
B No, friendship is neither inherited nor transitive.
C Yes, friends of friends are friends.
D Only in C++20.
Detailed Explanation: Friendship is strictly non-inherited and non-transitive; each class must explicitly grant access.