[ C++で開発 ]

クラスの設計

正統的標準形式または値クラス

C++の組み込み型(int, double等)と同じように、値として変数へ代入する、値宣言・引数や戻り値に使用することができるクラスを記述するイディオムが、正統的標準形式です。「C++プログラミングの筋と定石」(J.O.コプリエン著)で紹介されたものです。

正統的標準形式のサンプル

正統的標準形式として、WeatherData型を定義します。

WeatherData.h
#pragma once

class WeatherData {
public:
    WeatherData();
    WeatherData(const WeatherData&);
    WeatherData& operator=(const WeatherData&);
    ~WeatherData();
private:
    double temperatur;
    double humidity;
    double windSpeed;
    double windDirection;
};

正統的標準形式とするために定義する必要のあるメンバは、

です。

関数の引数・戻り値に値渡しで使用するときに、コピーコンストラクタが必要となります。

WeatherData.cpp
#include "WeatherData.h"

WeatherData::WeatherData() {
}

WeatherData::WeatherData(const WeatherData& w) {
}

WeatherData::~WeatherData() {
}

WeatherData& WeatherData::operator=(const WeatherData& rhs) {
    
}

参照クラス

値クラスのようにクラスのオブジェクトをコピーすると、不整合が生じるクラスを定義するイディオムです。リソースを管理するクラスなどが該当します。

参照クラスのサンプル

ファイルのアクセスを管理するクラス File 型を定義します。

File.h
#pragma once
#include <string>
#include <cstdio>

class File {
public:
    File(const std::string& aName);
    ~File();
private:
    File(const File&);
    File& operator=(const File&);
    std::string name_;
    std::FILE* fp_;
};

指定されたファイルへのアクセスを一元管理するFileオブジェクトがコピーされて複数存在すると、ファイル操作が不整合を生じます。そこで、コピーコンストラクタと代入演算子関数をprivateで宣言することでコピー不可とします。

File.cpp
#include "File.h"

File::File(const std::string& aName) {
    ...
}
File::~File() {
    ...
}

privateで宣言したコピーコンストラクタと代入演算子関数は、定義を記述しません。こうすることにより、仮にコピーコンストラクタや代入演算子を呼び出すコードがあったとしても、コンパイルエラーとなります。(private宣言していても、friend宣言されたクラス・関数や、Fileクラス内のメンバ関数から呼び出される可能性はあるため)

インタフェースクラス

別名プロトコルクラス。Javaのinterfaceと似た役割を果たすクラスです。