【初心者向け】C++ の開発環境をmacOS Sonomaと Docker Desktop 4.32 で構築してみよう!

記事の概要

この記事では、汎用プログラミング言語であるC++を使って、macOS Sonoma と Docker Desktop 4.32 での開発環境の構築からシンプルなCLIアプリ開発、実行までの流れを紹介します。

この記事を参考に、C++やCLIアプリ開発のスタートの一助となれば幸いです。


今回の記事の対象者

この記事は次のような方に向けています:

  • C++の環境を構築してアプリ開発を始めたい方
  • macOSとDockerコンテナを使ってローカルとサーバーの開発環境を構築したい方
  • シンプルなCLIアプリでC++の実装イメージを理解したい方

はじめに

今回は、C++を使った開発環境の構築と、シンプルなCLIアプリの開発を解説します。

開発環境は、以下2つの環境を構築します。

  • macOS:macOS Sonomaを使ったローカル開発環境
  • Dockerコンテナ:Docker Desktopを使ったサーバー開発環境

CLIアプリは、電卓アプリをオブジェクト指向プログラミングで開発し、C++の基礎的な機能を段階的に学べる構成にしています。

  • 四則演算
  • オブジェクト指向(クラス、メソッド、属性)

また、作成したソースコードをもとに、C++をどのように使っているかを詳細に解説していますので、是非活用してみてください。


目次


C++とは

C++は、1980年代にBjarne Stroustrupによって開発されたプログラミング言語です。C言語をベースにしていて、より複雑で大規模なプログラムを効率的に書けるようにするための機能が追加されています。

C++は、C言語の特徴を受け継ぎながら、柔軟で強力に進化しています。

その反面、他の言語に比べて学ぶのが少し難易度が高く、C++を使いこなすためには、プログラミングの基礎に加えて、オブジェクト指向についても理解する必要があるからです。

しかし、C++を学ぶことで、現在主流となっているJavaやPythonと言った、多くのプログラミング言語にも応用できる深い知識を得ることができます。


C++は、主に以下の特徴があります。

  1. オブジェクト指向プログラミング:
    • C++の最大の特徴の一つは「オブジェクト指向プログラミング」です。オブジェクト指向では、データとそれに関連する処理を「オブジェクト」としてまとめて扱います。これにより、プログラムの設計が分かりやすくなり、再利用もしやすくなります。
  2. 高いパフォーマンス
    • C++は、C言語と同様に、非常に効率的にプログラムを実行できます。高速な処理が求められるゲームやリアルタイムシステムなどに適しています。
  3. 柔軟性
    • C++は、低レベルな操作(ハードウェアに近い部分の操作)から高レベルな操作(オブジェクト指向などの高度なプログラミング技法)まで幅広く対応できるので、非常に柔軟な言語と言えます。
  4. ポインタとメモリ管理
    • C++では、メモリを手動で管理する機能があり、ポインタを使って直接メモリのアドレスにアクセスすることができます。これにより、メモリの効率的な使用が可能になりますが、メモリ操作にバグが発生するとプログラムがクラッシュするリスクもあります。

Cは、以下のようなソフトウェア開発に適しています。

  • ゲーム開発
    • 高速で効率的な処理が必要なゲーム開発でよく使われています。多くの有名なゲームエンジンもC++で書かれています。
  • システムソフトウェア
    • オペレーティングシステムやドライバなど、ハードウェアに近い部分のソフトウェアでもC++が使われています。
  • アプリケーションソフトウェア
    • 高機能なデスクトップアプリケーションやビジネスソフトウェアでもC++が使用されています。


ソフトウェア・ハードウェア

必要なツール、ライブラリ、端末は以下の通りです。

開発ツール

以下、開発ツールとその公式サイトの一覧です。本記事では直接以下のツールは使いませんが、導入しておくと開発作業が楽になります。

ツール名用途
CLionC/C++開発者向けのIDEです。個人非商用利用や学生は無料となっています。
VS CodeオープンソースのIDEです。色々なプラグインで環境を拡張できます。

端末

以下、今回の環境を構築する対象の端末スペックです。

項目詳細
ハードウェアApple Silicon M3, RAM 24GB
OSmacOS Sonoma 14.6

本記事で紹介するソフトウェアおよびツールは、筆者の個人的な使用経験に基づくものであり、公式のサポート外の設定や使用方法を含む場合があります。利用に際しては、公式サイトの指示およびガイドラインを参照し、自己責任で行ってください。


C++開発環境の構築

コンパイラのインストール

macOSでC開発環境を構築する場合、GCCとClangの2つの選択肢があります。どちらも強力なコンパイラですが、用途や環境によって適切な選択が異なります。Clangはモダンな開発環境やクロスプラットフォーム開発に強みがあり、GCCは長い歴史と幅広いプラットフォームへの対応が特徴です。プロジェクトやニーズに応じて、最適なコンパイラを選んでください。以下に、それぞれのコンパイラの特徴を記載します。

今回の記事では、安定性やDockerコンテナでの実績があるGCCに統一します。また、参考としてClangの導入方法も紹介します。

Clang:

特にmacOSやiOSの開発環境において標準的なコンパイラとして使われます。また、開発者向けツールや統合開発環境(IDE)に組み込まれることが多いです。

ClangはモダンなC++標準やC言語の拡張を早期にサポートすることが多く、新しい言語仕様やライブラリへの対応が迅速です。

クロスプラットフォーム対応が進んでおり、macOS、Linux、Windowsなどで使用できます。

GCC:

Linuxや多くのUnix系システムにおいて標準のコンパイラです。オープンソースプロジェクトやサーバー、組み込みシステムの開発に広く利用されています。

GCCは非常に広範なプラットフォームをサポートしており、特にLinux系システムでのデファクトスタンダードとなっています。

GCCは多くの古いコードベースやアーキテクチャに対して高い互換性を持っているため、レガシーシステムでの使用に適しています。

ClangとGCCのインストールについては、以下の記事で詳細に解説していますのでそちらをご覧下さい。


brewでインストール済のgccの情報を以下のコマンドで取得します。

brew info gcc

以下、筆者の環境での出力結果です。

(base) xxxxx@xxxxx calculator_app % brew info gcc
==> gcc: stable 14.1.0 (bottled), HEAD
GNU compiler collection
<https://gcc.gnu.org/>
Installed
/opt/homebrew/Cellar/gcc/14.1.0_2 (1,913 files, 473.3MB) *
  Poured from bottle using the formulae.brew.sh API on 2024-08-25 at 08:48:23
From: <https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/g/gcc.rb>
License: GPL-3.0-or-later with GCC-exception-3.1
==> Dependencies
Build: make ✘
Required: gmp ✔, isl ✔, libmpc ✔, mpfr ✔, zstd ✔
==> Options
--HEAD
	Install HEAD version
==> Analytics
install: 132,624 (30 days), 457,313 (90 days), 1,491,015 (365 days)
install-on-request: 55,390 (30 days), 195,833 (90 days), 622,618 (365 days)
build-error: 453 (30 days)
(base) xxxxx@xxxxx calculator_app %

インストールされているgccがバージョン14ですので、以下のコマンドでC++のコンパイラを呼び出すことが出来ます。

g++-14 --version

以下、筆者の環境での出力結果です。

(base) xxxxx@xxxxx bin % g++-14 --version
g++-14 (Homebrew GCC 14.1.0_2) 14.1.0
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

(base) xxxxx@xxxxx calculator_app %

この状態では、g++コマンドを呼び出すと、以下の様にclangが呼び出されます。

(base) xxxxx@xxxxx bin % g++ --version
Apple clang version 15.0.0 (clang-1500.3.9.4)
Target: arm64-apple-darwin23.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
(base) xxxxx@xxxxx bin % 

GCCコンパイラをg++コマンドで呼び出せるようにg++コマンドのシンボリックリンクを作成します。

(base) xxxxx@xxxxx bin % which g++-14
/opt/homebrew/bin/g++-14
(base) siwamin@orcusmba bin % sudo ln -s /opt/homebrew/bin/g++-14 /usr/local/bin/g++
Password:
(base) xxxxx@xxxxx bin % 

作成したコマンドを認識できるように、PATH変数に以下を追加します。筆者の環境は、zshを使って居るので、以下のファイルに追記して、ターミナルを再起動します。

.zshrc

export "PATH=/usr/local/bin:$PATH"

以下、筆者の環境での出力結果です。コンパイラが gccに変更出来たのが確認出来ます。

(base) xxxxx@xxxxx ~ % g++ --version
g++ (Homebrew GCC 14.1.0_2) 14.1.0
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

(base) xxxxx@xxxxx ~ % 

GCCからClangへの変更

GCCからClangに戻す場合は、以下のコマンドでシンボリックリンクを削除します。

% sudo unlink /usr/local/bin/g++


C++で「Hello World」アプリを作成する

c++のコンパイラが正しく動作しているか確認するため、最もシンプルな「Hello World」を出力するアプリを作成します。

ディレクトリ構成

プロジェクトのディレクトリ構成は次のようになります。任意のディレクトリにプロジェクトディレクトリ「hello」を作成してください。

/hello++
│
└── hello.cpp

次に、コンパイルしたいC++のプログラムを作成します。テキストエディタ(Vim)や、Visual Studio Code、Jetbrains CLion等のIDE(統合開発環境)を使用して、以下のCファイルを作成します。

手順:

  1. プロジェクトディレクトリを作成
    • ターミナルでディレクトリ作成コマンドを実行し、プロジェクトディレクトリ「hello++」を作成します。 mkdir hello++
    • 作成したディレクトリに移動します。 cd hello++
  2. 新しいC++ファイルを作成:
    • エディタを開き、以下の簡単なC++プログラムを入力します。
#include <iostream>

int main() {
    std::cout << "Hello, World!" << std::endl;
    return 0;
}
  • このファイルを「hello.cpp」という名前でプロジェクトディレクトリに保存します。

macOS用の開発環境確認

C++のプログラムをコンパイルする

ターミナルでコンパイルコマンドを実行し、C++のプログラムをコンパイルします。

手順:

  1. ターミナルを開く:
    • 再度、ターミナルを開きます。
  2. ソースファイルのあるディレクトリに移動:
    • cdコマンドを使って、C++ファイルを保存したディレクトリに移動します。
  3. コンパイルを実行:
    • 以下のコマンドを使って、C++プログラムをコンパイルします。ここでは、gccを使用していますが、clangでも同様にコンパイルできます。
    • このコマンドは、hello.cppというソースファイルをコンパイルして、helloという名前の実行ファイルを生成します。-oは出力ファイルの名前を指定するオプションです。
g++ hello.cpp -o hello

コンパイルされたプログラムを実行する

コンパイルが成功すると、生成された実行ファイルをターミナルで実行できます。

手順:

  1. 実行:
    • 以下のコマンドを入力して、コンパイルされたプログラムを実行します。
    • これで、ターミナルに「Hello, World!」と表示されます。
./hello

以下に、上記手順を実行したコマンド実行例を示します。

(base) xxxxx@xxxxx test-pj % mkdir hello++
(base) xxxxx@xxxxx test-pj % cd hello++ 
(base) xxxxx@xxxxx hello++ % vi hello.cpp
(base) xxxxx@xxxxx hello++ % g++ hello.cpp -o hello
(base) xxxxx@xxxxx hello++ % ./hello 
Hello, World!
(base) xxxxx@xxxxx hello++ % 

これで、macOS用のC++開発環境が出来ました!


Dockerコンテナ用

ディレクトリ構成

プロジェクトのディレクトリ構成は次のようになります。先ほどのmacOSの手順で作成したディレクトリとCファイルを使います。

/hello++
│
├── hello.cpp
└── Dockerfile

Docker Desktopのインストール

Dockerコンテナは、アプリケーションをコンテナと呼ばれる仮想的な環境に入れて動かすためのツールです。Docker Composeは、複数のコンテナを一度に管理するためのツールです。

Docker Desktopのインストールは、以下の記事を参考にしてください。

Dockerfileの作成

次に、Dockerfileを作成して、アプリをコンテナ化します。このファイルでは、Cコンパイラをインストールし、アプリをコンパイルして実行します。

# ベースイメージとしてAlpine Linuxを使用
FROM alpine:latest

# Cコンパイラをインストール
RUN apk add --no-cache g++

# アプリの作業ディレクトリを作成
WORKDIR /app

# Cコードをコンテナにコピー
COPY hello.cpp .

# Cコードをコンパイル
RUN g++ hello.cpp -o hello

# コンテナが起動したときに実行するコマンド
CMD ["./hello"]

アプリのビルドと実行

コンテナイメージのビルドコマンド

ビルドしたコンテナイメージ名に「hello-cpp」を指定しています。

docker build . -t hello-cpp

ビルドしたコンテナイメージの実行コマンド

docker run -it hello-cpp

hello++コンテナが起動して、ターミナルに「Hello, World!」と表示されます。

以下に、上記手順を実行したコマンド実行例を示します。

(base) xxxxx@xxxxx hello++ % vi Dockerfile
(base) xxxxx@xxxxx hello++ % docker build . -t hello-cpp
[+] Building 3.5s (10/10) FINISHED                         docker:desktop-linux
 => [internal] load build definition from Dockerfile                       0.0s
 => => transferring dockerfile: 439B                                       0.0s
 => [internal] load metadata for docker.io/library/alpine:latest           0.7s
 => [internal] load .dockerignore                                          0.0s
 => => transferring context: 2B                                            0.0s
 => CACHED [1/5] FROM docker.io/library/alpine:latest@sha256:0a4eaa0eecf5  0.0s
 => [internal] load build context                                          0.0s
 => => transferring context: 30B                                           0.0s
 => [2/5] RUN apk add --no-cache g++                                       2.3s
 => [3/5] WORKDIR /app                                                     0.0s 
 => [4/5] COPY hello.cpp .                                                 0.0s 
 => [5/5] RUN g++ hello.cpp -o hello                                       0.2s 
 => exporting to image                                                     0.3s 
 => => exporting layers                                                    0.3s 
 => => writing image sha256:94c0b58e5af466408c2d0ff253d70d72455f103fab1d9  0.0s 
 => => naming to docker.io/library/hello-cpp                               0.0s

View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/k6yzq788u4qtlijml76y50fcg
(base) xxxxx@xxxxx hello++ % docker run -it hello-cpp
Hello, World!
(base) xxxxx@xxxxx hello++ % 

これで、macOS上でC++のアプリを開発し、実行する環境が整いました!

Dockerを使うことで、どこでも同じ環境でアプリケーションを動かすことができるので、開発がスムーズになります。


電卓アプリの概要と学習のポイント

電卓アプリの設計を通じて、C++の基礎からオブジェクト指向プログラミングの初歩まで、段階的に学習します。

電卓アプリ(四則演算)の概要

ユーザーが入力した2つの数値に対して、四則演算を行い、その結果を表示する機能を持たせます。

電卓アプリの機能:

電卓アプリには、以下の機能を持たせます。

  • 加算(+)
  • 減算(-)
  • 乗算(*)
  • 除算(/)
  • 数値入力と結果表示

電卓アプリの流れ:

  1. プログラム開始時に、利用可能な操作を説明するメニューを表示します。
  2. ユーザーに1つ目の数値を入力させます。
  3. ユーザーに演算子(+, -, *, /)を入力させます。
  4. ユーザーに2つ目の数値を入力させます。
  5. 入力された数値と演算子に基づいて、計算を行います。
  6. 計算結果を表示します。

学習ポイント

  • クラスとオブジェクト:
    • CalculatorとInputHandlerというクラスを設計し、オブジェクト指向の基本を学びます。
  • メソッドの設計:
    • 各演算を個別のメソッドとして分け、責任分担を明確にする方法を学びます。
  • 状態管理:
    • current_valueやoperatorなど、電卓の状態をクラス内で管理することで、状態管理の基本を理解します。
  • 入力のバリデーション:
    • InputHandlerクラスで入力のバリデーションを行い、プログラムの堅牢性を学びます。

オブジェクト指向設計の導入

オブジェクト指向の概念を取り入れ、各機能をクラスとして分けて設計します。

クラスとオブジェクトは、プログラミングの中で「設計図」と「その設計図を基に作られた実物」に例えることができます。

【オブジェクト指向の基本概念】

  • クラス (Class):オブジェクトの設計図
    • クラスは、あるもの(オブジェクト)を作るための設計図のようなものです。例えば、「犬」というクラスを作るとします。このクラスは、すべての犬が持っている共通の特徴や行動を定義するための設計図になります。
  • 属性 (Attribute):その設計図が持つ特徴
    • 属性は、そのクラスが持っている特徴や性質です。例えば、「犬」クラスの属性には「名前」「年齢」「色」などがあります。これらは犬の具体的な情報を表します。
  • メソッド (Method):その設計図が持つ動作
    • メソッドは、そのクラスが持つ動作や機能のことです。例えば、「犬」クラスのメソッドには「吠える」「走る」などがあります。これらは犬ができることを表します。

電卓アプリのクラス設計

上記の概念を適用して、電卓アプリを以下のクラスに分けて設計します。

まずは「電卓」を作るための設計図を考えてみます。この設計図には、電卓が持つべき機能や特性まとめます。

Calculatorクラス: 電卓全体の操作を管理するクラス。

今回の電卓アプリでは、「Calculator」というクラスがその設計図に相当します。この設計図には、「足し算」「引き算」「掛け算」「割り算」をどうやって実行するかをまとめます。

属性は、オブジェクトが現在どんな「状態」にあるかを管理するデータのことです。電卓で言うと、今どの数字が入力されているか、どの演算子が選ばれているかなどが「状態」です。

  • 属性:
    • current_value: 現在の計算結果を保持する変数。
    • last_value: 前の計算値を保持する変数。
    • operator: 現在選択されている演算子(加算、減算など)を保持する変数。

メソッドは、クラスの中にある「操作」や「機能」です。電卓の例で言うと、「足し算する機能」や「引き算する機能」などがメソッドにあたります。

  • メソッド:
    • add(double value): 現在の値に指定された値を加算。
    • subtract(double value): 現在の値から指定された値を減算。
    • multiply(double value): 現在の値に指定された値を乗算。
    • divide(double value): 現在の値を指定された値で除算。
    • clear(): 計算をリセット。
    • calculate(): 現在の値と最後に入力された値を使って計算を実行。
    • set_operator(char op): 演算子を設定する。

InputHandlerクラス: ユーザー入力を管理するクラス。

  • 属性:
    • input_string: ユーザーからの現在の入力を保持する文字列。
  • メソッド:
    • get_input(): ユーザーから入力を受け取る。
    • validate_input(): 入力が有効かどうかを確認。
    • parse_input(): 入力を解析し、数値と演算子に分ける。

電卓アプリ(四則演算)

ディレクトリ構成

プロジェクトのディレクトリ構成は次のようになります。任意のディレクトリにプロジェクトディレクトリ「calculator_app」を作成してください。

/calculator_app
│
├── calculator.cpp
└── Dockerfile


電卓アプリのソースコード

電卓アプリのコードを以下に示します。

このファイルを「calculator.cpp」という名前でプロジェクトディレクトリに保存します。

calculator.cpp

#include <iostream>

class Calculator {
private:
    double current_value;
    double last_value;
    char op;

public:
    Calculator() : current_value(0), last_value(0), op('+') {}

    void set_value(double value) {
        last_value = current_value;
        current_value = value;
    }

    void set_operator(char new_op) {
        op = new_op;
    }

    void calculate() {
        switch (op) {
            case '+':
                current_value = last_value + current_value;
                break;
            case '-':
                current_value = last_value - current_value;
                break;
            case '*':
                current_value = last_value * current_value;
                break;
            case '/':
                if (current_value != 0) {
                    current_value = last_value / current_value;
                } else {
                    std::cerr << "Error: Division by zero." << std::endl;
                }
                break;
            default:
                std::cerr << "Error: Unknown operator." << std::endl;
                break;
        }
    }

    double get_result() {
        return current_value;
    }

    void clear() {
        current_value = 0;
        last_value = 0;
        op = '+';
    }
};

int main() {
    Calculator calc;
    double value;
    char op;

    std::cout << "Enter first number: ";
    std::cin >> value;
    calc.set_value(value);

    std::cout << "Enter operator (+, -, *, /): ";
    std::cin >> op;
    calc.set_operator(op);

    std::cout << "Enter second number: ";
    std::cin >> value;
    calc.set_value(value);

    calc.calculate();

    std::cout << "Result: " << calc.get_result() << std::endl;

    return 0;
}


学習ポイントの解説

クラスとは?

「Calculator」というクラスがその設計図に相当します。この設計図には、「足し算」「引き算」「掛け算」「割り算」をどうやって実行するかが書かれています。

class Calculator {
    // 設計図にあたる部分
    double current_value; // 現在の計算結果を保存する場所
    double last_value;    // 前の計算結果を保存する場所
    char op;              // 現在選択されている演算子

    // この後にメソッド(機能)が定義される
};

オブジェクトとは?

オブジェクトは、クラスという設計図から作られた「実物」です。電卓の設計図を基に、実際に動く電卓が組み立てられるように、クラスからオブジェクトが作られます。

int main() {
    Calculator calc; // Calculatorクラスという設計図から、calcという名前の電卓(オブジェクト)を作成
}

メソッドとは?

メソッドは、クラスの中にある「操作」や「機能」です。電卓の例で言うと、「足し算する機能」や「引き算する機能」などがメソッドにあたります。

「add(double value)」というメソッドは、電卓が足し算をするための機能です。電卓が持つ「加算機能」の設計図を書いているのがこのメソッドです。

void add(double value) {
    current_value = last_value + current_value;
}

このメソッドは、前に入力された値(last_value)と新しい値(current_value)を足して、その結果をcurrent_valueに保存します。

状態管理

状態管理は、アプリケーションが現在どんな「状態」にあるかを管理することです。電卓で言うと、今どの数字が入力されているか、どの演算子が選ばれているかなどが「状態」です。

今回のアプリでは、current_valueやlast_value、opが電卓の状態を表しています。

double current_value; // 現在の計算結果
double last_value;    // 前の計算値
char op;              // 選択されている演算子

opに「+」がセットされているなら、次に計算が実行されたときに足し算が行われます。このように、電卓の現在の状態をしっかり管理することで、正しい計算ができるようになっています。

入力のバリデーション

入力のバリデーションは、ユーザーが入力したデータが正しいかどうかをチェックすることです。電卓アプリでは、正しい数値が入力されているかや、割り算のときにゼロで割ろうとしていないかを確認します。

case '/':
    if (current_value != 0) {
        current_value = last_value / current_value;
    } else {
        std::cerr << "Error: Division by zero." << std::endl;
    }
    break;

このコードでは、current_valueがゼロでないかを確認し、ゼロならエラーを出します。


電卓アプリをコンパイルする

ターミナルでコンパイルコマンドを実行し、電卓アプリをコンパイルします。

手順:

  1. ターミナルを開く:
    • 再度、ターミナルを開きます。
  2. ソースファイルのあるディレクトリに移動:
    • cdコマンドを使って、C++ファイルを保存したディレクトリに移動します。
  3. コンパイルを実行:
    • 以下のコマンドを使って、C++プログラムをコンパイルします。ここでは、g++を使用しています。
    • このコマンドは、calculator.cppというソースファイルをコンパイルして、calculatorという名前の実行ファイルを生成します。-oは出力ファイルの名前を指定するオプションです。
g++ calculator.cpp -o calculator


コンパイルされた電卓アプリを実行する

コンパイルが成功すると、生成された実行ファイルをターミナルで実行できます。

手順①:ローカル環境(macOS上)のターミナルでの実行

  1. 実行:
    • 以下のコマンドを入力して、コンパイルされたプログラムを実行します。
./calculator

以下に、上記手順を実行したコマンド実行例を示します。

(base) xxxxx@xxxxx test-pj % mkdir calculator_app
(base) xxxxx@xxxxx test-pj % cd calculator_app
(base) xxxxx@xxxxx calculator_app2 % vi calculator.cpp
(base) xxxxx@xxxxx calculator_app2 % g++ calculator.cpp -o calculator

(base) xxxxx@xxxxx calculator_app2 % ./calculator 
Enter first number: 3
Enter operator (+, -, *, /): +
Enter second number: 3
Result: 6

(base) xxxxx@xxxxx calculator_app % ./calculator
Enter first number: 4
Enter operator (+, -, *, /): /
Enter second number: 0
Error: Division by zero.
Result: 0
(base) xxxxx@xxxxx calculator_app % 


手順②:Dockerコンテナでの実行

次に、Dockerfileを作成して、アプリをコンテナ化します。このファイルでは、Cコンパイラをインストールし、アプリをコンパイルして実行します。

# ベースイメージとしてAlpine Linuxを使用
FROM alpine:latest

# Cコンパイラをインストール
RUN apk add --no-cache g++

# アプリの作業ディレクトリを作成
WORKDIR /app

# Cコードをコンテナにコピー
COPY calculator.cpp .

# Cコードをコンパイル
RUN g++ calculator.cpp -o calculator

# コンテナが起動したときに実行するコマンド
CMD ["./calculator"]

コンテナイメージのビルドコマンド

ビルドしたコンテナイメージ名に「calculator」を指定しています。

docker build . -t calculator

ビルドしたコンテナイメージの実行コマンド

docker run -it calculator

calculatorアプリが起動して、入力待ちになります。

以下に、上記アプリの実行例を示します。

(base) xxxxx@xxxxx calculator_app % vi Dockerfile
(base) xxxxx@xxxxx calculator_app % docker build . -t calc-cpp 
[+] Building 1.9s (10/10) FINISHED                         docker:desktop-linux
 => [internal] load build definition from Dockerfile                       0.0s
 => => transferring dockerfile: 459B                                       0.0s
 => [internal] load metadata for docker.io/library/alpine:latest           1.6s
 => [internal] load .dockerignore                                          0.0s
 => => transferring context: 2B                                            0.0s
 => [1/5] FROM docker.io/library/alpine:latest@sha256:0a4eaa0eecf5f8c050e  0.0s
 => [internal] load build context                                          0.0s
 => => transferring context: 1.77kB                                        0.0s
 => CACHED [2/5] RUN apk add --no-cache g++                                0.0s
 => CACHED [3/5] WORKDIR /app                                              0.0s
 => [4/5] COPY calculator.cpp .                                            0.0s
 => [5/5] RUN g++ calculator.cpp -o calculator                             0.3s
 => exporting to image                                                     0.0s
 => => exporting layers                                                    0.0s
 => => writing image sha256:f17757f68c56d12fec39e7bedbe15c09cd35b51caa4c6  0.0s
 => => naming to docker.io/library/calc-cpp                                0.0s

View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/t6ryplg84o5u5vfp8qrbvh4ic
(base) xxxxx@xxxxx calculator_app % docker run -it calc-cpp         
Enter first number: 6
Enter operator (+, -, *, /): *
Enter second number: 3
Result: 18
(base) xxxxx@xxxxx calculator_app % 


終了とクリーンアップ

作業が終わった後、開発環境を終了し、不要なリソースをクリーンアップします。Docerコンテナはイメージをビルドする度に、データを消費しますので、利用しないイメージはこまめに削除するのがお薦めです。

クリーンアップ

不要になったDockerのリソースを削除します。

docker system prune


まとめ

この記事では、汎用プログラミング言語であるC++を使って、macOS Sonoma と Docker Desktop 4.32 での開発環境の構築からシンプルなCLIアプリ開発、実行までの流れを紹介しました。

今回のC++の開発環境の手順では、まずmacOSでClangやGCCをインストールし、開発環境を整えました。さらに、Dockerコマンドを使ってアプリケーションをコンテナで実行できるように設定し、どこでも同じ環境で動作させる力を身につけました。

さらに、このプロジェクトでは、C++の重要な概念を段階的に学習しました。クラスとオブジェクトを通じて、プログラムの設計図とその実体化を理解し、メソッドの設計を通じて操作や機能の定義方法を学びました。

これらを組み合わせることで、実用的で動作する電卓アプリを作成できるようになり、プログラミングの楽しさや達成感を味わうことができたのであれば大変嬉しいです!

プログラムを一行ずつ書き進め、動くものを作り上げる過程は、まるでパズルを解くような楽しさがあり、今回のプロジェクトを通じて、自分で作ったものが実際に動くという喜びを提供できたのであれば幸いです。

最後に、この記事がC++の学習やアプリ開発に役立つことを願っています。

SNSでもご購読できます。

コメントを残す

*


reCaptcha の認証期間が終了しました。ページを再読み込みしてください。