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

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

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

参照は、プログラミングにおいて変数や関数といったメモリ空間上での所在を指示するデータのことを指します。その中にはデータ自体は含まれず、他の場所にある情報を間接的に指示するプログラムです。

C++

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

Q&A

解決済

1回答

1118閲覧

c++ 参照 class

_._._ami

総合スコア26

参照

参照は、プログラミングにおいて変数や関数といったメモリ空間上での所在を指示するデータのことを指します。その中にはデータ自体は含まれず、他の場所にある情報を間接的に指示するプログラムです。

C++

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

0グッド

0クリップ

投稿2020/07/29 00:37

編集2020/07/29 02:03

//で書かれているコメントの指示を完成させたいのですが,間違えているところや空欄の部分を一部でもわかるところを教えて頂けると助かります.

追記:f4まではあってました! 
classのところからが分からないです.
全部自分で埋めてみたのですが以下のエラーがでます.

11th.ref.cpp:87:8: error: class member cannot be redeclared double sum(XYZ a){ ^ 11th.ref.cpp:76:16: note: previous definition is here double sum(XYZ a) ^ 11th.ref.cpp:175:2: error: expected '}' } ^ 11th.ref.cpp:51:10: note: to match this '{' class XYZ{ ^ 11th.ref.cpp:107:12: error: no viable conversion from returned value of type 'double' to function return type 'XYZ' return a.x*a.y*a.z; ^~~~~~~~~~~ 11th.ref.cpp:51:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'double' to 'const XYZ &' for 1st argument class XYZ{ ^ 11th.ref.cpp:51:7: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'double' to 'XYZ &&' for 1st argument class XYZ{ ^ 11th.ref.cpp:173:10: error: invalid operands to binary expression ('std::__1::ostream' (aka 'basic_ostream<char>') and 'XYZ') cout << f7(xyz) << "\n"; ~~~~ ^ ~~~~~~~ 11th.ref.cpp:175:2: error: expected ';' after class } ^

c++

1#include <iostream> 2using namespace std; 3 4// 課題の指示は,// のコメントに書かれている /**/ の方は無視しても構わないが,参考にしてもらいたい. 5double f1(double a) 6{ 7 a = a + 1; 8 return a; 9} 10double f2(double& a) 11{ 12 a = a + 1; 13 return a; 14} 15double f2p(double* a) 16{ 17 *a = *a + 1; 18 return *a; 19} 20double& f3(double& a) 21{ 22 return a; 23} 24 25double& f4(double& a) 26{ 27 a = a + 1; 28 return a; 29} 30 31class XYZ{ 32 double x, y, z; 33public: 34 XYZ(double xa, double ya, double za){ 35 // メンバ変数の x, y, z をそれぞれ xa, xy, za で初期化すること 36 (*this).x = xa; 37 (*this).y = ya; 38 (*this).z = za; 39 } 40 void add(double xa, double ya, double za){ 41 // メンバ変数の x, y, z にそれぞれ xa, xy, za を加算すること 42 x += xa; 43 y += ya; 44 z += za; 45 } 46 47 double& getRef(int i){ 48 //i = 1 なら x,i = 2 なら y, i = 3 なら z の参照を返すこと 49 if(i==1) return x; 50 if(i==2) return y; 51 if(i==3) return z; 52 } 53 friend double sum(XYZ a); // (4) 54 // f7 の関数が private メンバ x, y, z を参照できるように,friend 指定をして以下に記述.(4) の sum を参考にすること. 55 // f7 や sum はそもそもメンバ関数として実装すれば friend など必要ないのだが,ここでは練習のためにこの実装に取り組んでもらいたい. 56 double sum(XYZ a) 57 { 58 double x,y,z; 59 return x+y+z; 60 } 61 62XYZ& f5(XYZ& a){ 63 64 return a; 65} 66 67double sum(XYZ a){ 68 // (4) で friend が指定されているため,XYZ の private メンバである x, y, z を参照可能 69 return a.x + a.y + a.z; 70} 71 72// 関数 f6 を作成する. 73// 引数: XYZ 型変数の参照を一つ 74// 戻り値: 受け取った引数の参照 75// 処理内容: 引数メンバ変数 x, y, z の値を全て 1 加算 76// (2) の行で 9 と出力されるように作成すること 77XYZ& f6(XYZ& a){ 78 x = x+1; 79 y = y+1; 80 z = z+1; 81} 82// 関数 f7 を作成する 83// 引数: XYZ 型変数を一つ 84// 戻り値: double 型 85// 処理内容: 引数のメンバ x, y, z の積を返す 86XYZ f7(XYZ a){ 87 return a.x*a.y*a.z; 88} 89 90 91// 正しい出力を以下に示す.同じになるよう頑張ってもらいたい. 92// --- basic type part --- 93// 1 94// 2 95// 1 96// 2 97// 3 98// 4 99// 4 100// 4 101// 4 102// 5 103// 6 104// 9 105// --- class part --- 106// 9 107// 10 108// 11 109// 9 110// 18 111// 210 112 113int main() 114{ 115 double x = 1; 116 cout << "--- basic type part ---\n"; 117 cout << x << "\n"; 118 cout << f1(x) << "\n"; 119 cout << x << "\n"; 120 f2(x); /* equivalent to x = x + 1;*/ 121 cout << x << "\n"; 122 cout << f2(x) << "\n"; 123 cout << f2p(&x) << "\n"; 124 cout << x << "\n"; 125 f3(x) = 4; /* equivalent to x = 4;*/ 126 cout << x << "\n"; 127 cout << f3(x) << "\n"; 128 f3(f3(x)) = 5; /* equivalent to x = 5;*/ 129 cout << x << "\n"; 130 f4(x); // equivalent to x = x + 1; 131 cout << x << "\n"; 132 f4(f4(f4(x))); /* equivalent to x = x + 1; x = x + 1; x = x + 1;*/ 133 cout << x << "\n"; // (1) 134 135 cout << "--- class part ---\n"; 136 137 XYZ xyz(1,1,1); 138 xyz.add(1,1,1); 139 f5(xyz).add(7, 8, 9); /* equivalent to xyz.add(7, 8, 9);*/ 140 141 cout << xyz.getRef(1) << "\n"; 142 cout << xyz.getRef(2) << "\n"; 143 cout << xyz.getRef(3) << "\n"; 144 145 xyz.getRef(1) = 1; 146 xyz.getRef(2) = 2; 147 xyz.getRef(3) = 3; 148 f6(xyz); 149 cout << sum(xyz) << "\n"; // (2) 150 f6(f6(f6(xyz))); 151 cout << xyz.getRef(1) + xyz.getRef(2) + xyz.getRef(3) << "\n"; // (3), sum(xyz) と同値である. 152 cout << f7(xyz) << "\n"; 153 return 0; 154}

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

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

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

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

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

episteme

2020/07/29 02:37

class XYZ { に対し }; がありません。コンパイルエラー。
guest

回答1

0

ベストアンサー

aimztmyrskさん
結構前の質問ですが失礼します。

質問文のコードを読んでみて

  • クラスの最後の};が無い。
  • f6にreturnが無い。
  • sum関数をfriend化している。(ゲッターがあるのでその必要なし)
  • using namespace std;を使っている。
  • メンバにアクセスする際(*this).メンバという方法を取っている。(this->メンバ でよい)
  • 引数の変数名が分かりづらい。
  • ゲッターに入力制限を設けていない。

といった点が気になりました。

下記に自分なりに書き換えたコードを乗せるのでこれで動くか確認してみてください。
(私の環境では正常に動きました)

c++

1#include <iostream> 2#include <cassert> 3 4//////////////// 5// 6// 関数f1~f4 7// 8//////////////// 9double f1(const double var){return var + 1;} 10double f2(double& var){return var += 1;} 11double f2p(double* var){return *var += 1;} 12double& f3(double& var){return var;} 13double& f4(double& var){return var += 1;} 14 15////////////// 16// 17// XYZクラス 18// 19////////////// 20 21class XYZ{ 22 double x_, y_, z_; 23 24 public: 25 //XYZクラスで使用する定数 26 static constexpr unsigned int X = 0; 27 static constexpr unsigned int Y = 1; 28 static constexpr unsigned int Z = 2; 29 30 public: 31 XYZ(const double x, const double y, const double z):x_(x),y_(y),z_(z){} 32 33 void add(const double x, const double y, const double z){ 34 this->x_ += x; 35 this->y_ += y; 36 this->z_ += z; 37 } 38 39 double& getRef(const unsigned int index){ 40 assert(index<=Z);// 今回のように定数で処理を切り替えたいのならassertで入力制限設けたほうが良いかと思われます。 41 return index==X ? this->x_ : index==Y ? this->y_ : this->z_; 42 } 43}; 44 45//////////////////////////// 46// 47// XYZクラスにまつわる関数 48// 49//////////////////////////// 50XYZ& f5(XYZ& xyz){return xyz;} 51 52XYZ& f6(XYZ& xyz){ 53 xyz.getRef(XYZ::X) += 1; 54 xyz.getRef(XYZ::Y) += 1; 55 xyz.getRef(XYZ::Z) += 1; 56 return xyz; 57} 58 59double sum(XYZ& xyz){return xyz.getRef(XYZ::X) + xyz.getRef(XYZ::Y) + xyz.getRef(XYZ::Z);}// 注意点:XYZにはメンバ変数の参照を返すゲッターがあるのでfriend化不要 60double f7(XYZ& xyz){return xyz.getRef(XYZ::X) * xyz.getRef(XYZ::Y) * xyz.getRef(XYZ::Z);} 61 62//////////////// 63// 64// メイン関数 65// 66/////////////// 67int main(){ 68 auto x = double(1); 69 70 std::cout << "--- basic type part ---\n"; 71 std::cout << x << "\n"; 72 std::cout << f1(x) << "\n"; 73 std::cout << x << "\n"; 74 f2(x); /* equivalent to x = x + 1;*/ 75 std::cout << x << "\n"; 76 std::cout << f2(x) << "\n"; 77 std::cout << f2p(&x) << "\n"; 78 std::cout << x << "\n"; 79 f3(x) = 4; /* equivalent to x = 4;*/ 80 std::cout << x << "\n"; 81 std::cout << f3(x) << "\n"; 82 f3(f3(x)) = 5; /* equivalent to x = 5;*/ 83 std::cout << x << "\n"; 84 f4(x); // equivalent to x = x + 1; 85 std::cout << x << "\n"; 86 f4(f4(f4(x))); /* equivalent to x = x + 1; x = x + 1; x = x + 1;*/ 87 std::cout << x << "\n"; // (1) 88 89 std::cout << "--- class part ---\n"; 90 91 auto xyz = XYZ(1,1,1); 92 xyz.add(1,1,1); 93 f5(xyz).add(7, 8, 9); /* equivalent to xyz.add(7, 8, 9);*/ 94 95 std::cout << xyz.getRef(XYZ::X) << "\n"; 96 std::cout << xyz.getRef(XYZ::Y) << "\n"; 97 std::cout << xyz.getRef(XYZ::Z) << "\n"; 98 99 xyz.getRef(XYZ::X) = 1; 100 xyz.getRef(XYZ::Y) = 2; 101 xyz.getRef(XYZ::Z) = 3; 102 f6(xyz); 103 std::cout << sum(xyz) << "\n"; // (2) 104 f6(f6(f6(xyz))); 105 std::cout << xyz.getRef(XYZ::X) + xyz.getRef(XYZ::Y) + xyz.getRef(XYZ::Z) << "\n"; // (3), sum(xyz) と同値である. 106 std::cout << f7(xyz) << "\n"; 107 108 return 0; 109} 110

見当違いな回答でしたら申し訳ございません。

追記

friendはオブジェクト指向の三大要素の内の一つ
カプセル化に反する機能です。
やむを得ない事情がない限り
好き好んで使わないほうが良いかと思われます。
もし頭の中にfriendが浮かんだのなら
ゲッターで解決できないか考えてみては
いかがでしょうか。

投稿2020/08/06 19:42

編集2020/08/06 22:26
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

_._._ami

2020/08/09 08:41

ご丁寧に本当にありがとうございます...!!!知らないこともたくさんあり勉強になりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問