質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

2722閲覧

C++ 構造体同士での型変換のやり方

piced

総合スコア60

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2021/07/03 06:04

編集2021/07/03 09:55

#目的
C++でのゲーム制作をしています。
UnityにあるVector2,Vector3構造体の真似をして
自分で同じような構造体を作ろうとしています。
#質問
Unityでは
Vector3 = Vector2; のように
Vector3とVector2の異なる構造体同士での+-*/の演算や代入ができますが、
どのように実装するのでしょうか。
#試したができなかったこと
(Vector3.hに書くとき)
型変換関数の実装

C++

1//Vector3.h 2operator Vector2(); //error C2833: 'operator Vector2' は演算子または型指定子のどちらでもありません。

関数で変換する

C++

1//Vector3.h 2Vector2 ToVector2(); //error C3646: 'ToVector2': 不明なオーバーライド指定子です 3

#気づいたこと
両方の.hで互いにインクルードを行っているため問題が起きているようです。
片方の.hでもう片方へのインクルードをやめるとビルドが通ります。

ですがこれでは、双方向の型変換ができなくなってしまいます。
#コード

C++

1//Vector3.h 2#pragma once 3#include "Vector2.h" 4 5struct Vector3 6{ 7 union 8 { 9 float v[3]; 10 struct 11 { 12 float x; 13 float y; 14 float z; 15 }; 16 }; 17 18 19 static const Vector3 zero; 20 static const Vector3 right; 21 static const Vector3 left; 22 static const Vector3 up; 23 static const Vector3 down; 24 static const Vector3 forward; 25 static const Vector3 back; 26 27 Vector3(); //全要素を0.0fとしたVector3を作成します 28 Vector3(float); //全要素を引数値としたVector3を作成します 29 Vector3(float, float, float); //引数xyzを成分としたVector3を作成します 30 31 float DistanceToPoint(Vector3); //pointへの距離を返します 32 float Magnitude(); //ベクトルの長さを返します 33 Vector3 Normalized(); //このベクトルの単位ベクトルを返します 34 void Normalize(); //このベクトルを単位ベクトルに直します 35 36 //それぞれの要素同士で演算を行います 37 Vector3 operator+(Vector3); 38 Vector3 operator-(Vector3); 39 Vector3 operator*(Vector3); 40 Vector3 operator/(Vector3); 41 Vector3 operator+=(Vector3); 42 Vector3 operator-=(Vector3); 43 Vector3 operator*=(Vector3); 44 Vector3 operator/=(Vector3); 45 46 //全ての要素と演算を行います 47 Vector3 operator=(float); 48 Vector3 operator+(float); 49 Vector3 operator-(float); 50 Vector3 operator*(float); 51 Vector3 operator/(float); 52 Vector3 operator+=(float); 53 Vector3 operator-=(float); 54 Vector3 operator*=(float); 55 Vector3 operator/=(float); 56};

C++

1//Vector2.h 2#pragma once 3 4#include "Vector3.h" 5 6struct Vector2 7{ 8 union 9 { 10 float v[2]; 11 struct 12 { 13 float x; 14 float y; 15 }; 16 }; 17 18 static const Vector2 zero; 19 static const Vector2 right; 20 static const Vector2 left; 21 static const Vector2 up; 22 static const Vector2 down; 23 24 Vector2(); //全要素を0.0fとしたVector2を作成します 25 Vector2(float num); //全要素を引数値としたVector2を作成します 26 Vector2(float x, float y); //引数xyを成分としたVector2を作成します 27 28 float DistanceToPoint(Vector2 point); //pointへの距離を返します 29 float Magnitude(); //ベクトルの長さを返します 30 Vector2 Normalized(); //このベクトルの単位ベクトルを返します 31 void Normalize(); //このベクトルを単位ベクトルに直します 32 33 //同じ要素同士で演算を行います 34 Vector2 operator+(Vector2); 35 Vector2 operator-(Vector2); 36 Vector2 operator*(Vector2); 37 Vector2 operator/(Vector2); 38 Vector2 operator+=(Vector2); 39 Vector2 operator-=(Vector2); 40 Vector2 operator*=(Vector2); 41 Vector2 operator/=(Vector2); 42 43 //全ての要素と演算を行います 44 Vector2 operator=(float); 45 Vector2 operator+(float); 46 Vector2 operator-(float); 47 Vector2 operator*(float); 48 Vector2 operator/(float); 49 Vector2 operator+=(float); 50 Vector2 operator-=(float); 51 Vector2 operator*=(float); 52 Vector2 operator/=(float); 53}; 54

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

相互にインクルードしているため、インクルードガードが効いてしまっているためのエラーかと思います。

C++

1//Vector3.h 2#pragma once 3#include "Vector2.h" 4 5//Vector2.h 6#pragma once 7#include "Vector3.h"

①ヘッダでは互いに前方参照にして、.cppでヘッダをインクルードして実装する。

C++

1//Vector3.h 2#pragma once 3struct Vector2; 4 5//Vector2.h 6#pragma once 7struct Vector3; 8 9//Vector3.cpp 10#include "Vector2.h" 11operator Vector3(){} // 実装 12 13//Vector2.cpp 14#include "Vector3.h" 15operator Vector2(){} // 実装

②Vector2とVector3を同じヘッダにまとめる

//Vector.h // 前方参照 struct Vector2; struct Vector3; // 宣言 struct Vector2 { operator Vector3(); }; struct Vector3 { operator Vector2(); }; // 実装 inline Vector2::operator Vector3(){} inline Vector3::operator Vector2(){}

投稿2021/07/03 09:56

編集2021/07/03 09:57
Serbonis

総合スコア586

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

piced

2021/07/03 10:10

迅速な返答ありがとうございます。 どうやら私は前方参照を知らなかったようで、それでエラーが起きていたようです。 無事解決致しました。
guest

0

型変換operator、できません?

C++

1#include <iostream> 2 3class foo { 4public: 5 int n; 6 void print() { std::cout << "foo(" << n << ")\n"; } 7}; 8 9class bar { 10public: 11 bar(int v) : n(v) {} 12 int n; 13 operator foo() { foo tmp; tmp.n = n; return tmp; } 14}; 15 16int main() { 17 bar b(123); 18 foo f; f = b; // ここで型変換。 19 f.print(); 20}

[追記」相互変換? できますとも。

C++

1#include <iostream> 2 3class bar; 4 5class foo { 6public: 7 int n; 8 foo(int v=0) : n(v) {} 9 void print() { std::cout << "foo(" << n << ")\n"; } 10 operator bar(); 11}; 12 13class bar { 14public: 15 bar(int v=0) : n(v) {} 16 int n; 17 void print() { std::cout << "bar(" << n << ")\n"; } 18 operator foo(); 19}; 20 21bar::operator foo() { foo tmp; tmp.n = n; return tmp; } 22foo::operator bar() { bar tmp; tmp.n = n; return tmp; } 23 24int main() { 25 foo f0(123); 26 foo f1; 27 bar b0(456); 28 bar b1; 29 f1 = b0; f1.print(); 30 b1 = f0; b1.print(); 31}

投稿2021/07/03 06:26

編集2021/07/03 10:01
episteme

総合スコア16612

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

piced

2021/07/03 09:52

Vector3.hでVector2.hをインクルードするだけならうまくいきますが Vector2.h、Vector3.hの両方が互いをインクルードすると問題が発生します。 片方のインクルードの一行を消すとうまくいきますが、 これでは型変換が片方の型からしか出来ません。
episteme

2021/07/03 10:01

ついきしました。
piced

2021/07/03 10:08

迅速な返答ありがとうございます。 どうやら私は前方参照を知らなかったようで、それでエラーが起きていたようです。 わずかではありますが他の方が先に助言してくださったので、 BAはその方に上げたいと思います。 改めて、ありがとうございました。
guest

0

Unityは詳しくありませんが

C++では普通に演算子のユーザ定義が可能です。3次元ベクトルと2次元ベクトルの加減算を定義しても問題ありません。(本人の責任の範囲で使うならば)

投稿2021/07/03 07:06

HogeAnimalLover

総合スコア4830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

piced

2021/07/03 09:49

どういうわけか出来ませんでした //Vector3.h Vector3 operator+(Vector2); //error C2061: 構文エラー: 識別子 'Vector2' Vector3.hでVector2.hをインクルードするだけならうまくいきますが Vector2.h、Vector3.hの両方が互いをインクルードすると問題が発生します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問