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

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

新規登録して質問してみよう
ただいま回答率
85.46%
C++

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

Q&A

解決済

2回答

667閲覧

規定型からクラスへの暗黙変換について

Watching

総合スコア56

C++

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

0グッド

0クリップ

投稿2021/01/27 04:29

編集2021/01/27 04:31

トランプに関連するクラスを自作している時、奇妙に思える挙動に巡り合いました。

c++

1#include <iostream> 2#include <string> 3 4class Card { 5 private: 6 int suit; 7 public: 8 Card(int i) { suit = i; }; 9 Card(std::string);//入力された文字に対応した数字を代入します 10 int num() const { return suit + 1; }; 11 operator int() const { return suit; } 12 std::string str() const;//対応した文字列を返します 13 static Card numtocard(int i) { return Card(i - 1); } 14}; 15 16void func(Card card){}; 17 18int main(){ 19 int i = 4; 20 cout << ((Card)i).str();//5 21 cout << ((Card)"3").str();//3 22 func(i); 23}; 24

奇妙なことに、intからCard型への型変換を定義していないにも関わらず、intからCard型へのキャストができてしまっています。デバッグしてみると、(Card)i は Card(i) と同じように扱われています。さらには、暗黙的な型変換さえ行えてしまいます。
なぜこのような挙動が起きるのでしょうか。そう定義されているのですか?

このような挙動には問題があるように思えます。ユーザーが作成したクラスへの意図しないキャストが行われる可能性があり、バグの温床になるのではないでしょうか。

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

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

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

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

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

guest

回答2

0

ベストアンサー

intからCard型への型変換が定義していないにも関わらず、

あなたの以下のコードが型変換を定義しています。

c++

1 Card(int i) { suit = i; };

型変換を意図していないなら、explicitをつけます。

c++

1 explicit Card(int i) { suit = i; };

投稿2021/01/27 04:31

int32_t

総合スコア21008

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

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

Watching

2021/01/27 04:49

別件なんですけれども、 Card(1) <= Card(1) というような記述ができることに気が付きましたが、これは、左側の値を勝手にint型に変換して<=演算子を適用しているということですか?
int32_t

2021/01/27 04:58

はい。operator int() が定義されているので比較可能になってますね。
Watching

2021/01/27 05:10

ちなみに、別の、他の型への変換が定義されてる時の優先度はどうなっていますか?
guest

0

intからCard型への型変換を定義していないにも関わらず、intからCard型へのキャストができてしまっています。

あなたの意図に反して、ご自身の手でCardint型相互の暗黙型変換を実装しています。

cpp

1class Card { 2 // ... 3public: 4 // A) int型からCard型への暗黙型変換(コンストラクタ) 5 Card(int i); 6 // B) Card型からint型への暗黙型変換(型変換演算子) 7 operator int() const; 8 // ... 9};

さらには、暗黙的な型変換さえ行えてしまいます。
なぜこのような挙動が起きるのでしょうか。そう定義されているのですか?

前掲コードのように定義される型変換A),B)ともに、C++言語ではデフォルトで 暗黙の型変換 として扱われます。これにより、プログラマの意図に反するであろう下記コードもコンパイルされてしまいます。

cpp

1Card a = 4, b = 3; // 暗黙のint→Card変換 2bool r = (a > b); // 暗黙のCard→int変換結果に対して比較>を適用

このような挙動には問題があるように思えます。ユーザーが作成したクラスへの意図しないキャストが行われる可能性があり、バグの温床になるのではないでしょうか。

指摘されるように暗黙の型変換はとかくバグの温床になります。explicitキーワードを用いて 明示的な型変換 に修正することをお薦めします。もしくは、クラス設計上本当に型変換を提供する必然性があるかを再考ください。

cpp

1class Card { 2 // ... 3public: 4 // A') int型からCard型への明示型変換(コンストラクタ) 5 explict Card(int i); 6 // B') Card型からint型への明示型変換(型変換演算子) 7 explict operator int() const; 8 // ... 9}; 10 11// 暗黙型変換を要求する下記はコンパイルエラー 12Card a = 4, b = 3; 13bool r = (a > b); 14 15// 明示的な型変換であれば許容される 16Card a(4), b(3); 17bool r = (int(a) > int(b));

投稿2021/01/28 04:52

yohhoy

総合スコア6191

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問