brokenpassbyrefconst.cc
#include <iostream> // cout, endl
#include <cstdlib> // EXIT_SUCCESS
void BrokenPrintSquare(const int& i) {
i = i*i; // Compiler error here.
std::cout << i << std::endl;
}
int main(int argc, char** argv) {
int j = 2;
BrokenPrintSquare(j);
return EXIT_SUCCESS;
}
constmadness.cc
#include <cstdlib> // EXIT_SUCCESS
int main(int argc, char** argv) {
int x = 5; // x is an int
const int y = 6; // y is a (const int)
y++; // compiler error
const int* z = &y; // z is a (variable pointer) to a (const int)
*z += 1; // compiler error
z++; // ok
int* const w = &x; // w is a (const pointer) to a (variable int)
*w += 1; // ok
w++; // compiler error
const int* const v = &x; // v is a (const pointer) to a (const int)
*v += 1; // compiler error
v++; // compiler error
return EXIT_SUCCESS;
}
styleguide.cc
#include <cstdlib> // EXIT_SUCCESS
void CalcArea(const int& width, const int& height, int* const area) {
*area = width * height;
}
int main(int argc, char** argv) {
int w = 10, h = 20, a;
CalcArea(w, h, &a);
return EXIT_SUCCESS;
}
Point.h
#ifndef POINT_H_
#define POINT_H_
// Class that represents a two-dimesional integral coordinate plane
class Point {
public:
Point(int x, int y); // constructor
int get_x() const { return x_; } // inline member function
int get_y() const { return y_; } // inline member function
double Distance(const Point &p) const; // member function
void SetLocation(int x, int y); // member function
private:
int x_; // data member
int y_; // data member
}; // class Point
#endif // POINT_H_
Point.cc
#include "Point.h"
#include <cmath> // sqrt
Point::Point(const int x, const int y) {
// BAD STYLE: shouldn't mix-and-match direct field access (x_)
// and access via this (this->y_).
x_ = x;
this->y_ = y; // this-> is optional, unless names conflict
}
double Point::Distance(const Point& p) const {
// We can access p's x_ and y_ variables either through the
// get_x(), get_y() accessor functions, or the x_, y_ private
// member variables directly, since we're in a member function of
// the same class (BAD STYLE to mix-and-match, though).
double distance = (x_ - p.get_x()) * (x_ - p.get_x());
distance += (y_ - p.y_) * (y_ - p.y_);
return sqrt(distance);
}
void Point::SetLocation(const int x, const int y) {
x_ = x;
y_ = y;
}
usepoint.cc
#include "Point.h"
#include <iostream>
#include <cstdlib>
using std::cout;
using std::endl;
int main(int argc, char** argv) {
Point p1(1, 2);
Point p2(4, 6);
cout << "p1 is: (" << p1.get_x() << ", ";
cout << p1.get_y() << ")" << endl;
cout << "p2 is: (" << p2.get_x() << ", ";
cout << p2.get_y() << ")" << endl;
cout << "dist : " << p1.Distance(p2) << endl;
return EXIT_SUCCESS;
}
FileDescriptor.h
#ifndef FILE_DESCRIPTOR_H_
#define FILE_DESCRIPTOR_H_
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
class FileDescriptor {
public:
explicit FileDescriptor(const char* file) { // Constructor
fd_ = open(file, O_RDONLY);
// On error, we get fd_ = -1
// error handling is in the Destructor
}
~FileDescriptor() { // Destructor
// No need to close an invalid descriptor
if (fd_ != -1) {
int res = close(fd_);
if (res == -1) {
std::cerr << "Error Closing File" << std::endl;
}
}
}
int get_fd() const { return fd_; } // inline member function
private:
int fd_; // data member
}; // class FileDescriptor
#endif // FILE_DESCRIPTOR_H_
use_fd.cc
#include <cstdlib>
#include <iostream>
#include "FileDescriptor.h"
int main(int argc, char** argv) {
FileDescriptor fd1("foo.txt");
FileDescriptor fd2(fd1);
return EXIT_SUCCESS;
}
Makefile
CC = g++
CFLAGS = -Wall -g -std=c++17
PROGS = styleguide usepoint SimplePoint use_fd
PROGS2 = brokenpassbyreference constmadness
all: $(PROGS)
brokenpassbyreference: brokenpassbyreference.cc
$(CC) $(CFLAGS) -o $@ $<
constmadness: constmadness.cc
$(CC) $(CFLAGS) -o $@ $<
styleguide: styleguide.cc
$(CC) $(CFLAGS) -o $@ $<
usepoint: usepoint.o Point.o
$(CC) $(CFLAGS) -o $@ $^
usepoint.o: usepoint.cc Point.h
$(CC) $(CFLAGS) -c $<
Point.o: Point.cc Point.h
$(CC) $(CFLAGS) -c $<
SimplePoint: SimplePoint.cc SimplePoint.h
$(CC) $(CFLAGS) -o $@ $<
use_fd: use_fd.cc FileDescriptor.h
$(CC) $(CFLAGS) -o $@ $<
clean:
rm -f $(PROGS) $(PROGS2) *.o