メンバ関数の引数に自分と同じ型を設定したい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
jay
記事: 314
登録日時: 13年前
住所: 大阪市
連絡を取る:

メンバ関数の引数に自分と同じ型を設定したい

#1

投稿記事 by jay » 10年前

やりたいことはタイトル通りですが、以下のような構造体を作ろうとしました

コード:

//int型2次元座標
typedef struct
{
	int x;	//X座標
	int y;	//Y座標

	//値の加算
	//引数:加算する値を設定したPos_t構造体
	void Add(Pos_t SetPos)
	{
		x += SetPos.x;
		y += SetPos.y;
	}
	//値の加算
	//引数:加算する値を設定したint型データ(x, y)
	void Add(int sx, int sy)
	{
		x += sx;
		y += sy;
	}
}Pos_t;
コンパイルすると1つめのAdd関数の所でエラーが出ます
エラー 1 error C2061: 構文エラー : 識別子 'Pos_t'

これはPos_tの定義がないからダメって言ってるのだと推測してます
つまりメンバ関数の引数にそのまま自分自身の型を渡すことはできないのでしょうか?

渡す方法があれば教えてください
ちなみにエディターは Visual C++ 2010 Express です
♪僕たちは まだ森の中 抜け出そう 陽のあたる場所へ

アバター
Tatu
記事: 445
登録日時: 13年前
住所: 北海道

Re: メンバ関数の引数に自分と同じ型を設定したい

#2

投稿記事 by Tatu » 10年前

自己参照構造体のやり方を使えばできそうな気がしますがどうでしょうか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: メンバ関数の引数に自分と同じ型を設定したい

#3

投稿記事 by softya(ソフト屋) » 10年前

C++なんですから、これではダメでしょうか?

コード:

struct Pos_t
{
    int x;  //X座標
    int y;  //Y座標
 
    //値の加算
    //引数:加算する値を設定したPos_t構造体
    void Add(Pos_t SetPos)
    {
        x += SetPos.x;
        y += SetPos.y;
    }
    //値の加算
    //引数:加算する値を設定したint型データ(x, y)
    void Add(int sx, int sy)
    {
        x += sx;
        y += sy;
    }
};
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Milla

Re: メンバ関数の引数に自分と同じ型を設定したい

#4

投稿記事 by Milla » 10年前

コンパイラは上から順にコンパイルするんですが、
void Add(Pos_t SetPos)
この時点でtypedef構文が終わってません。
なのでPos_tが何なのかコンパイラには理解できません。

コード:

//int型2次元座標

typedef struct _Pos_t Pos_t;

struct _Pos_t
{
	int x;  //X座標
	int y;  //Y座標

	//値の加算
	//引数:加算する値を設定したPos_t構造体
	void Add(Pos_t SetPos)
	{
		x += SetPos.x;
		y += SetPos.y;
	}
	//値の加算
	//引数:加算する値を設定したint型データ(x, y)
	void Add(int sx, int sy)
	{
		x += sx;
		y += sy;
	}
};

Milla

Re: メンバ関数の引数に自分と同じ型を設定したい

#5

投稿記事 by Milla » 10年前

typedef struct _NAME{
}NAME;

は構造体の宣言と構造体の定義と型定義を同時に行っていることを忘れてはいけません。

構造体の宣言
struct _NAME;

構造体の宣言かつ定義
struct _NAME{
};

型定義
typedef struct _NAME NAME;

soft屋さんの書いているとおり、C++では構造体はすべてがデフォルトでパブリックなクラスなので
class NAME;とかいてNAME objNAMEと変数を作れるように
struct NAME;とかいてNAME objNAMEと変数を作れます。

アバター
usao
記事: 1887
登録日時: 11年前

Re: メンバ関数の引数に自分と同じ型を設定したい

#6

投稿記事 by usao » 10年前

_Pos_t だとか _NAME とかいうのは予約語の規則に違反してますよ.
オフトピック
何やらこの掲示板では
typedef struct { ... } name; のように構造体を無名にする書き方をよく見かける気がしますが
そうすることで何かメリットあるんでしょうか? 扱い難いだけだと思うのすが.

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: メンバ関数の引数に自分と同じ型を設定したい

#7

投稿記事 by softya(ソフト屋) » 10年前

オフトピック
typedef struct { ... } name; のように構造体を無名にする書き方をよく見かける気がしますが
まぁ、前方参照しない限りにおいては構造体名は不要なので付ける必要のない名前を付けるのは無駄手間という考え方もあると思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
Tatu
記事: 445
登録日時: 13年前
住所: 北海道

Re: メンバ関数の引数に自分と同じ型を設定したい

#8

投稿記事 by Tatu » 10年前

>>usaoさん,softya(ソフト屋)さん
>No:6,No:7のOfftopic
それについてはDixqさんに聞いたほうがよいかと思います。

追記:
構造体のタグ名を下線で始めることについて

株式会社きじねこのC/C++迷信集
[迷信] 構造体のタグ名は下線で始める
http://www.kijineko.co.jp/tech/supersti ... score.html

に書かれていました。

naohiro19
記事: 256
登録日時: 13年前
住所: 愛知県

Re: メンバ関数の引数に自分と同じ型を設定したい

#9

投稿記事 by naohiro19 » 10年前

Milla さんが書きました:typedef struct _NAME{
}NAME;

は構造体の宣言と構造体の定義と型定義を同時に行っていることを忘れてはいけません。

構造体の宣言
struct _NAME;

構造体の宣言かつ定義
struct _NAME{
};

型定義
typedef struct _NAME NAME;

soft屋さんの書いているとおり、C++では構造体はすべてがデフォルトでパブリックなクラスなので
class NAME;とかいてNAME objNAMEと変数を作れるように
struct NAME;とかいてNAME objNAMEと変数を作れます。
[迷信] 構造体のタグ名は下線で始める | 株式会社きじねこ
このコードの動作は未定義だということをご存知でしょうか? _FOO のように、下線(アンダースコア、アンダーバー)で始まり、下線または大文字が続く識別子は「予約済み識別子」です。予約済み識別子というのは、規格がライブラリに使うか、処理系が作業用または拡張用に使うために予約されている識別子で、それらをユーザープログラムで使用することはできません(使用した場合の動作は未定義です)。

jay
記事: 314
登録日時: 13年前
住所: 大阪市
連絡を取る:

Re: メンバ関数の引数に自分と同じ型を設定したい

#10

投稿記事 by jay » 10年前

回答ありがとうございます

今回はMillaさんが教えて下さった方法で思い通りの実装をすることができました

コード:

typedef struct 2DPosition_Type_t Pos_t;

//int型2次元座標
struct 2DPosition_Type_t
{
	int x;	//X座標
	int y;	//Y座標

	//値の加算
	//引数:加算する値を設定したPos_t構造体
	void Add(Pos_t SetPos)
	{
		x += SetPos.x;
		y += SetPos.y;
	}
	//値の加算
	//引数:指定方向のDir定数配列
	void Add(const int Add[2])
	{
		x += Add[0];
		y += Add[1];
	}
};
ご協力して下さった皆様、ありがとうございます。


>usaoさん
typedef struct { ... } name; のように構造体を無名にする書き方をよく見かける気がしますが
そうすることで何かメリットあるんでしょうか? 扱い難いだけだと思うのすが.
Tatuさんがおっしゃる通り、これはDixqさんに聞いた方がいいと思います。
僕も龍神録の館からゲームプログラミングを学んだクチで
今は「このやり方が自分にとって分かりやすいから」と言う理由でこの書き方をしているだけですので(苦笑)
(と言ったら理屈を理解せずに使ってるのか、って怒られそうですけど)
♪僕たちは まだ森の中 抜け出そう 陽のあたる場所へ

milla

Re: メンバ関数の引数に自分と同じ型を設定したい

#11

投稿記事 by milla » 10年前

迷信だったんですか
これは申し訳ない

ただ、タイプデフで同じ名前にすると
vsのインテリセンスで衝突したはずですので
ソフト屋さんの書き方が一番安全かと思われます。

Mana

Re: メンバ関数の引数に自分と同じ型を設定したい

#12

投稿記事 by Mana » 10年前

タグ名と型名を同じにすると問題があるというのも迷信だね。

コード:

struct Hoge {
    Hoge(const Hoge &hoge);
};

コード:

typedef struct Hoge Hoge;
struct Hoge {
    Hoge *hoge;
};
typedef structの無名構造体は迷信の普及に貢献してるね。

閉鎖

“C言語何でも質問掲示板” へ戻る