diff --git a/README.md b/README.md index 2cdcc8a..cb411da 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ Examples include (and will expand to): * [rot47](./rot47/) * OOP * [virtual-interface](./virtual-interface/) + * [oop-with-exception](./oop-with-exception/) --- diff --git a/oop-with-exception/Makefile b/oop-with-exception/Makefile new file mode 100644 index 0000000..ab8b3c0 --- /dev/null +++ b/oop-with-exception/Makefile @@ -0,0 +1,31 @@ +# pull in shared compiler settings +include ../common.mk + +# per-example flags +# CXXFLAGS += -pthread + +## get it from the folder name +TARGET := $(notdir $(CURDIR)) +## all *.cpp files in this folder +SRCS := $(wildcard *.cpp) +OBJS := $(SRCS:.cpp=.o) + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CXX) $(CXXFLAGS) -o $@ $^ + +%.o: %.cpp + $(CXX) $(CXXFLAGS) -c $< -o $@ + +run: $(TARGET) + ./$(TARGET) $(ARGS) + +clean: + rm -f $(OBJS) $(TARGET) + +# Delegates to top-level Makefile +check-format: + $(MAKE) -f ../Makefile check-format DIR=$(CURDIR) + +.PHONY: all clean run check-format diff --git a/oop-with-exception/main.cpp b/oop-with-exception/main.cpp new file mode 100644 index 0000000..a5250f6 --- /dev/null +++ b/oop-with-exception/main.cpp @@ -0,0 +1,47 @@ +/** +This example creates two classes A and B, where class B is a member of class A. +And in the constructor of class A, it prints a message and throws an exception. +So what would be the output? + +B's constructor called. +A's constructor called. +B's destructor called. +Caught exception: Exception in A's constructor + +If an exception leaves a constructor, the object’s destructor does not run, because the object never finished +construction. But destructors for already-constructed members/base-subobjects do run. +*/ + +#include +#include + +class B +{ + public: + B() { std::cout << "B's constructor called." << std::endl; } + ~B() { std::cout << "B's destructor called." << std::endl; } +}; + +class A +{ + private: + B b; // Member of class B + public: + A() + { + std::cout << "A's constructor called." << std::endl; + throw std::runtime_error("Exception in A's constructor"); + } + ~A() { std::cout << "A's destructor called." << std::endl; } +}; + +int +main() +{ + try { + A a; // Attempt to create an instance of A + } catch (const std::exception& e) { + std::cout << "Caught exception: " << e.what() << std::endl; + } + return 0; +} diff --git a/oop-with-exception/oop-with-exception b/oop-with-exception/oop-with-exception new file mode 100755 index 0000000..1e86554 Binary files /dev/null and b/oop-with-exception/oop-with-exception differ diff --git a/oop-with-exception/tests.sh b/oop-with-exception/tests.sh new file mode 100755 index 0000000..67f4b30 --- /dev/null +++ b/oop-with-exception/tests.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +set -ex + +./oop-with-exception