0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【C++】オペレーターでの演算子のオーバーロード

Last updated at Posted at 2025-01-25

Unity機能を作ろう!

用途 : クラスのオブジェクトを組み込み型のように扱う

基本形 : 型 operator 演算子(引数) { 処理文 }

Vector2

Vector2.h
#pragma once

class Vector2
{
public:
#pragma region 特殊(定数)ベクトルの宣言
	static const Vector2 zero;
	static const Vector2 one;
	static const Vector2 up;
	static const Vector2 down;
	static const Vector2 left;
	static const Vector2 right;
#pragma endregion

#pragma region XY
	// 共用体
	union
	{
		// 無名構造体(アノニマス構造体)でラップする
		struct
		{
			float x, y;
		};
		float value[2];
	};
#pragma endregion

#pragma region コンストラクタとデストラクタ
	Vector2() = default;
	Vector2(const Vector2&) = default;	// コピーコンストラクタ
	//Vector2(const Vector2&&);			// ムーブコンストラクタ
	Vector2(float x, float y);
	Vector2(float v[2]);
	virtual ~Vector2() = default;
#pragma endregion

#pragma region 演算子のオーバーロード(演算子の追加)
	// 四則演算(2項演算子)
	Vector2 operator + (const Vector2& v) const;
	Vector2 operator - (const Vector2& v) const;
	Vector2 operator * (const float& v) const;
	Vector2 operator / (const float& v) const;

	// 代入演算(2項演算子)
	const Vector2& operator= (const Vector2& v);
	const Vector2& operator+=(const Vector2& v);
	const Vector2& operator-=(const Vector2& v);
	const Vector2& operator*=(const float& v);
	const Vector2& operator/=(const float& v);

	// 単項演算子 -
	const Vector2& operator- ();

	// 比較演算子
	bool operator==(const Vector2& v)const;
	bool operator!=(const Vector2& v)const;
#pragma endregion

#pragma region Unity関数(代入なし, 内部使用).
	float Magnitude()const;
	float SqrMagnitude()const;
	Vector2 Normalize()const;
#pragma endregion

#pragma region Unity関数(代入あり, 外部使用)
	static float Magnitude(const Vector2& v);
	static float SqrMagnitude(const Vector2& v);
	static Vector2 Normalize(const Vector2& v);
	static float Distance(const Vector2& v1, const Vector2& v2);
	static float Dot(const Vector2& v1, const Vector2& v2);
	static float Angle(const Vector2& v1, const Vector2& v2);
#pragma endregion
};
Vector2.cpp
#include "Vector2.h"

// 特殊(定数)ベクトルの定義
const Vector2 Vector2::zero = { 0,0 };
const Vector2 Vector2::one = { 1,1 };
const Vector2 Vector2::up = { 0,1 };
const Vector2 Vector2::down = { 0,-1 };
const Vector2 Vector2::left = { -1,0 };
const Vector2 Vector2::right = { 1,0 };

/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="x">x座標の初期化値</param>
/// <param name="y">y座標の初期化値</param>
Vector2::Vector2(float x, float y)
	:x(x)
	, y(y)
{}

/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="x">x座標の初期化値</param>
/// <param name="y">y座標の初期化値</param>
Vector2::Vector2(float v[2])
	:x(v[0])
	, y(v[1])
{}

/// <returns>Vector2同士の足し算の結果</returns>
Vector2 Vector2::operator+(const Vector2& v)const
{
	return Vector2(this->x + v.x, this->y + v.y);
}

/// <returns>Vector2同士の引き算の結果</returns>
Vector2 Vector2::operator-(const Vector2& v) const
{
	return Vector2(this->x - v.x, this->y - v.y);
}

/// <returns>float値をVector2の要素にそれぞれを掛けた結果</returns>
Vector2 Vector2::operator*(const float& v) const
{
	return Vector2(this->x * v, this->y * v);
}

/// <returns>float値をVector2の要素にそれぞれを割った結果</returns>
Vector2 Vector2::operator/(const float& v) const
{
	if (v == 0)return 0;
	return Vector2(this->x / v, this->y / v);
}

/// <summary>
/// Vector2からVector2へ代入する
/// </summary>
const Vector2& Vector2::operator=(const Vector2& v)
{
	this->x = v.x;
	this->y = v.y;
	return *this;
}

/// <summary>
/// Vector2にVector2を足す
/// </summary>
const Vector2& Vector2::operator+=(const Vector2& v)
{
	this->x += v.x;
	this->y += v.y;
	return *this;
}

/// <summary>
/// Vector2からVector2を引く
/// </summary>
const Vector2& Vector2::operator-=(const Vector2& v)
{
	this->x -= v.x;
	this->y -= v.y;
	return *this;
}

/// <summary>
/// Vector2のそれぞれの要素にfloat値を掛ける
/// </summary>
const Vector2& Vector2::operator*=(const float& v)
{
	this->x *= v;
	this->y *= v;
	return *this;
}

/// <summary>
/// Vector2のそれぞれの要素からfloat値を割る
/// </summary>
const Vector2& Vector2::operator/=(const float& v)
{
	if (v == 0)return 0;
	this->x /= v;
	this->y /= v;
	return *this;
}

/// <summary>
/// Vector2の符号を反転させる
/// </summary>
const Vector2& Vector2::operator-()
{
	return (*this * (-1));
}

/// <returns>true = 引数のVector2と全く同じ, false = 引数のVector2と異なる</returns>
bool Vector2::operator==(const Vector2& v) const
{
	return this->x == v.x && this->y == v.y;
}

/// <returns>true = 引数のVector2と異なる部分がある, false = 引数のVector2と全く同じ</returns>
bool Vector2::operator!=(const Vector2& v) const
{
	return this->x != v.x || this->y != v.y;
}

//#include<math.h>	// C言語の数学ヘッダー
#include<cmath>		// C++の数学ヘッダー

/// <returns>ベクトルの大きさ</returns>
float Vector2::Magnitude()const
{
	// sqrtは平方根の計算
	return 	std::sqrtf(this->x * this->x + this->y * this->y);
}

/// <returns>ベクトルの大きさ(平方根除外済み)</returns>
float Vector2::SqrMagnitude()const
{
	// 平方根を避ける
	return 	Magnitude() * Magnitude();
}

/// <summary>
/// 正規化
/// </summary>
Vector2 Vector2::Normalize()const
{
	return *this / this->Magnitude();
}

/// <returns>ベクトルの大きさ</returns>
float Vector2::Magnitude(const Vector2& v)
{
	// sqrtは平方根の計算
	return std::sqrtf(v.x * v.x + v.y * v.y);
}

/// <returns>ベクトルの大きさ(平方根除外済み)</returns>
float Vector2::SqrMagnitude(const Vector2& v)
{
	// 平方根を避ける
	return Magnitude(v) * Magnitude(v);
}

/// <summary>
/// 正規化
/// </summary>
Vector2 Vector2::Normalize(const Vector2& v)
{
	return v / v.Magnitude();
}

/// <summary>
/// Vector2からVector2の距離を測る
/// </summary>
float Vector2::Distance(const Vector2& v1, const Vector2& v2)
{
	//return std::sqrtf((v1.x-v2.x)*(v1.x-v2.x)+(v1.y-v2.y)*(v1.y-v2.y));
	return Magnitude(v1 - v2);
}

/// <returns>Vector2同士の掛け算の結果(内積)</returns>
float Vector2::Dot(const Vector2& v1, const Vector2& v2)
{
	return v1.x * v2.x + v1.y * v2.y;
}

/// <returns>ベクトルの間の角度(範囲 : 0 ~ 180度)</returns>
float Vector2::Angle(const Vector2& v1, const Vector2& v2)
{
	// acosはアークコサインの計算
	return acos(Dot(v1.Normalize(), v2.Normalize())) * 180;
}

Vector3

Vector3.h
#pragma once

class Vector3
{
public:
#pragma region 特殊(定数)ベクトルの宣言
	static const Vector3 zero;
	static const Vector3 one;
	static const Vector3 up;
	static const Vector3 down;
	static const Vector3 left;
	static const Vector3 right;
	static const Vector3 forward;
	static const Vector3 back;
#pragma endregion

#pragma region XYZ
	// 共用体
	union
	{
		// 無名構造体(アノニマス構造体)でラップする
		struct
		{
			float x, y, z;
		};
		float value[3];
	};
#pragma endregion

#pragma region コンストラクタとデストラクタ
	Vector3() = default;
	Vector3(const Vector3&) = default;	// コピーコンストラクタ
	//Vector3(const Vector3&&);			// ムーブコンストラクタ
	Vector3(float x, float y, float z = 0.0f);
	Vector3(float v[3]);
	virtual ~Vector3() = default;
#pragma endregion

#pragma region 演算子のオーバーロード(演算子の追加)
	// 四則演算(2項演算子)
	Vector3 operator + (const Vector3& v) const;
	Vector3 operator - (const Vector3& v) const;
	Vector3 operator * (const float& v) const;
	Vector3 operator / (const float& v) const;

	// 代入演算(2項演算子)
	const Vector3& operator= (const Vector3& v);
	const Vector3& operator+=(const Vector3& v);
	const Vector3& operator-=(const Vector3& v);
	const Vector3& operator*=(const float& v);
	const Vector3& operator/=(const float& v);

	// 単項演算子 -
	const Vector3& operator- ();

	// 比較演算子
	bool operator==(const Vector3& v)const;
	bool operator!=(const Vector3& v)const;
#pragma endregion

#pragma region Unity関数(代入なし, 内部使用).
	float Magnitude()const;
	float SqrMagnitude()const;
	Vector3 Normalize()const;
#pragma endregion

#pragma region Unity関数(代入あり, 外部使用)
	static float Magnitude(const Vector3& v);
	static float SqrMagnitude(const Vector3& v);
	static Vector3 Normalize(const Vector3& v);
	static float Distance(const Vector3& v1, const Vector3& v2);
	static float Dot(const Vector3& v1, const Vector3& v2);
	static float Cross(const Vector3& v1, const Vector3& v2);
	static float Angle(const Vector3& v1, const Vector3& v2);
#pragma endregion
};
Vector3.cpp
#include "Vector3.h"

// 特殊(定数)ベクトルの定義
const Vector3 Vector3::zero = { 0,0,0 };
const Vector3 Vector3::one = { 1,1,1 };
const Vector3 Vector3::up = { 0,1,0 };
const Vector3 Vector3::down = { 0,-1,0 };
const Vector3 Vector3::left = { -1,0,0 };
const Vector3 Vector3::right = { 1,0,0 };
const Vector3 Vector3::forward = { 0,0,1 };
const Vector3 Vector3::back = { 0,0,-1 };

/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="x">x座標の初期化値</param>
/// <param name="y">y座標の初期化値</param>
/// <param name="z">z座標の初期化値</param>
Vector3::Vector3(float x, float y, float z)
	:x(x)
	, y(y)
	, z(z)
{}

/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="x">x座標の初期化値</param>
/// <param name="y">y座標の初期化値</param>
/// <param name="z">z座標の初期化値</param>
Vector3::Vector3(float v[3])
	:x(v[0])
	, y(v[1])
	, z(v[2])
{}

/// <returns>Vector3同士の足し算の結果</returns>
Vector3 Vector3::operator+(const Vector3& v)const
{
	return Vector3(this->x + v.x, this->y + v.y, this->z + v.z);
}

/// <returns>Vector3同士の引き算の結果</returns>
Vector3 Vector3::operator-(const Vector3& v) const
{
	return Vector3(this->x - v.x, this->y - v.y, this->z - v.z);
}

/// <returns>float値をVector3の要素にそれぞれを掛けた結果</returns>
Vector3 Vector3::operator*(const float& v) const
{
	return Vector3(this->x * v, this->y * v, this->z * v);
}

/// <returns>float値をVector3の要素にそれぞれを割った結果</returns>
Vector3 Vector3::operator/(const float& v) const
{
	if (v == 0)return 0;
	return Vector3(this->x / v, this->y / v, this->z / v);
}

/// <summary>
/// Vector3からVector3へ代入する
/// </summary>
const Vector3& Vector3::operator=(const Vector3& v)
{
	this->x = v.x;
	this->y = v.y;
	this->z = v.z;
	return *this;
}

/// <summary>
/// Vector3にVector3を足す
/// </summary>
const Vector3& Vector3::operator+=(const Vector3& v)
{
	this->x += v.x;
	this->y += v.y;
	this->z += v.z;
	return *this;
}

/// <summary>
/// Vector3からVector3を引く
/// </summary>
const Vector3& Vector3::operator-=(const Vector3& v)
{
	this->x -= v.x;
	this->y -= v.y;
	this->z -= v.z;
	return *this;
}

/// <summary>
/// Vector3のそれぞれの要素にfloat値を掛ける
/// </summary>
const Vector3& Vector3::operator*=(const float& v)
{
	this->x *= v;
	this->y *= v;
	this->z *= v;
	return *this;
}

/// <summary>
/// Vector3のそれぞれの要素からfloat値を割る
/// </summary>
const Vector3& Vector3::operator/=(const float& v)
{
	if (v == 0)return 0;
	this->x /= v;
	this->y /= v;
	this->z /= v;
	return *this;
}

/// <summary>
/// Vector3の符号を反転させる
/// </summary>
const Vector3& Vector3::operator-()
{
	return (*this * (-1));
}

/// <returns>true = 引数のVector3と全く同じ, false = 引数のVector3と異なる</returns>
bool Vector3::operator==(const Vector3& v) const
{
	return this->x == v.x && this->y == v.y && this->z == v.z;
}

/// <returns>true = 引数のVector3と異なる部分がある, false = 引数のVector3と全く同じ</returns>
bool Vector3::operator!=(const Vector3& v) const
{
	return this->x != v.x || this->y != v.y || this->z != v.z;
}

//#include<math.h>	// C言語の数学ヘッダー
#include<cmath>		// C++の数学ヘッダー

/// <returns>ベクトルの大きさ</returns>
float Vector3::Magnitude()const
{
	// sqrtは平方根の計算
	return 	std::sqrtf(this->x * this->x + this->y * this->y + this->z * this->z);
}

/// <returns>ベクトルの大きさ(平方根除外済み)</returns>
float Vector3::SqrMagnitude()const
{
	// 平方根を避ける
	return 	Magnitude() * Magnitude();
}

/// <summary>
/// 正規化
/// </summary>
Vector3 Vector3::Normalize()const
{
	return *this / this->Magnitude();
}

/// <returns>ベクトルの大きさ</returns>
float Vector3::Magnitude(const Vector3& v)
{
	// sqrtは平方根の計算
	return std::sqrtf(v.x * v.x + v.y * v.y + v.z * v.z);
}

/// <returns>ベクトルの大きさ(平方根除外済み)</returns>
float Vector3::SqrMagnitude(const Vector3& v)
{
	// 平方根を避ける
	return Magnitude(v) * Magnitude(v);
}

/// <summary>
/// 正規化
/// </summary>
Vector3 Vector3::Normalize(const Vector3& v)
{
	return v / v.Magnitude();
}

/// <summary>
/// Vector3からVector3の距離を測る
/// </summary>
float Vector3::Distance(const Vector3& v1, const Vector3& v2)
{
	//return std::sqrtf((v1.x-v2.x)*(v1.x-v2.x)+(v1.y-v2.y)*(v1.y-v2.y)+(v1.z-v2.z)*(v1.z-v2.z));
	return Magnitude(v1 - v2);
}

/// <returns>Vector3同士の掛け算の結果(内積)</returns>
float Vector3::Dot(const Vector3& v1, const Vector3& v2)
{
	return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}

/// <returns>外積</returns>
float Vector3::Cross(const Vector3& v1, const Vector3& v2)
{
	return v1.x * v2.y - v1.x * v2.z,
		v1.y* v2.x - v1.y * v2.z,
		v1.z* v2.x - v1.z * v2.y;
}

/// <returns>ベクトルの間の角度(範囲 : 0 ~ 180度)</returns>
float Vector3::Angle(const Vector3& v1, const Vector3& v2)
{
	// acosはアークコサインの計算
	return acos(Dot(v1.Normalize(), v2.Normalize())) * 180;
}

Color

Color.h
#pragma once

class Color
{
public:
#pragma region 特殊(定数)ベクトルの宣言
	static const Color black;
	static const Color blue;
	static const Color clear;
	static const Color cyan;
	static const Color gray;
	static const Color green;
	static const Color grey;
	static const Color magenta;
	static const Color red;
	static const Color white;
	static const Color yellow;
#pragma endregion

#pragma region RGBA
	// 共用体
	union
	{
		// 無名構造体(アノニマス構造体)でラップする
		struct
		{
			float r, g, b, a;
		};
		float value[4];
	};
#pragma endregion

#pragma region コンストラクタとデストラクタ
	Color() = default;
	Color(const Color&) = default;	// コピーコンストラクタ
	//Vector3(const Vector3&&);			// ムーブコンストラクタ
	Color(float r, float g, float b, float a);
	Color(float v[4]);
	virtual ~Color() = default;
#pragma endregion

#pragma region 演算子のオーバーロード(演算子の追加)
	// 四則演算(2項演算子)
	Color operator + (const Color& v) const;
	Color operator - (const Color& v) const;
	Color operator * (const float& v) const;
	Color operator / (const float& v) const;

	// 代入演算(2項演算子)
	const Color& operator= (const Color& v);
	const Color& operator+=(const Color& v);
	const Color& operator-=(const Color& v);
	const Color& operator*=(const float& v);
	const Color& operator/=(const float& v);

	// 比較演算子
	bool operator==(const Color& v)const;
	bool operator!=(const Color& v)const;
#pragma endregion
};
Color.cpp
#include "Color.h"

// 特殊(定数)ベクトルの定義
const Color Color::black = { 0,0,0,1 };
const Color Color::blue = { 0,0,1,1 };
const Color Color::clear = { 0,0,0,0 };
const Color Color::cyan = { 0,1,1,1 };
const Color Color::gray = { 0.5f,0.5f,0.5f,1 };
const Color Color::green = { 0,1,0,0 };
const Color Color::grey = { 0.5f,0.5f,0.5f,1 };
const Color Color::magenta = { 1,0,1,1 };
const Color Color::red = { 1,0,0,1 };
const Color Color::white = { 1,1,1,1 };
const Color Color::yellow = { 1,0.92f,0.016f,1 };

/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="r">赤色の初期化値</param>
/// <param name="g">緑色の初期化値</param>
/// <param name="b">青色の初期化値</param>
/// <param name="a">透明度の初期化値</param>
Color::Color(float r, float g, float b, float a)
	:r(r)
	, g(g)
	, b(b)
	, a(a)
{}

/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="r">赤色の初期化値</param>
/// <param name="g">緑色の初期化値</param>
/// <param name="b">青色の初期化値</param>
/// <param name="a">透明度の初期化値</param>
Color::Color(float v[4])
	:r(v[0])
	, g(v[1])
	, b(v[2])
	, a(v[3])
{}

/// <returns>Color同士の足し算の結果</returns>
Color Color::operator+(const Color& v)const
{
	return Color(this->r + v.r, this->g + v.g, this->b + v.b, this->a + v.a);
}

/// <returns>Color同士の引き算の結果</returns>
Color Color::operator-(const Color& v) const
{
	return Color(this->r - v.r, this->g - v.g, this->b - v.b, this->a - v.a);
}

/// <returns>float値をColorの要素にそれぞれを掛けた結果</returns>
Color Color::operator*(const float& v) const
{
	return Color(this->r * v, this->g * v, this->b * v, this->a * v);
}

/// <returns>float値をColorの要素にそれぞれを割った結果</returns>
Color Color::operator/(const float& v) const
{
	if (v == 0)return 0;
	return Color(this->r / v, this->g / v, this->b / v, this->a / v);
}

/// <summary>
/// ColorからColorへ代入する
/// </summary>
const Color& Color::operator=(const Color& v)
{
	this->r = v.r;
	this->g = v.g;
	this->b = v.b;
	this->a = v.a;
	return *this;
}

/// <summary>
/// ColorにColorを足す
/// </summary>
const Color& Color::operator+=(const Color& v)
{
	this->r += v.r;
	this->g += v.g;
	this->b += v.b;
	this->a += v.a;
	return *this;
}

/// <summary>
/// ColorからColorを引く
/// </summary>
const Color& Color::operator-=(const Color& v)
{
	this->r -= v.r;
	this->g -= v.g;
	this->b -= v.b;
	this->a -= v.a;
	return *this;
}

/// <summary>
/// Colorのそれぞれの要素にfloat値を掛ける
/// </summary>
const Color& Color::operator*=(const float& v)
{
	this->r *= v;
	this->g *= v;
	this->b *= v;
	this->a *= v;
	return *this;
}

/// <summary>
/// Colorのそれぞれの要素からfloat値を割る
/// </summary>
const Color& Color::operator/=(const float& v)
{
	if (v == 0)return 0;
	this->r /= v;
	this->g /= v;
	this->b /= v;
	this->a /= v;
	return *this;
}

/// <returns>true = 引数のColorと全く同じ, false = 引数のColorと異なる</returns>
bool Color::operator==(const Color& v) const
{
	return this->r == v.r && this->g == v.g && this->b == v.b && this->a == v.a;
}

/// <returns>true = 引数のColorと異なる部分がある, false = 引数のColorと全く同じ</returns>
bool Color::operator!=(const Color& v) const
{
	return this->r != v.r || this->g != v.g || this->b != v.b || this->a != v.a;
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?