X



【急募】ガチのマジでC++に詳しいプログラマ来てくれ!!
■ このスレッドは過去ログ倉庫に格納されています
0001以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 19:59:25.004ID:VLCsyyom0
class Range
{
public:
Range(int from, int to);
const float from;
const float to;
}

例えば上のようなクラスがあったとして、メンバ変数を初期化する際にfrom < toであることをチェックしてから初期化する、みたいなことがしたいんだけど可能?
コンスタント呼ぶ前に外部でチェックするのは無しで
0002以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:00:18.029ID:Inx+y79f0
コンストラクタとかないの?
0003以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:00:52.168ID:rePCrRO50
コンストラクタで例外なげろ
0004以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:01:39.595ID:wVpIqItD0
コンストラクタで例外
0005以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:02:10.033ID:VLCsyyom0
>>2
>>3
コンストラクタの中でチェックすると初期化が先に走っちゃう
0006以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:03:34.661ID:Inx+y79f0
コンストラクタで例外投げるでいいよね
0007以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:04:23.094ID:VLCsyyom0
>>6
初期化する前に例外を投げたい
0008以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:05:58.946ID:wVpIqItD0
コンストラクタ呼ぶ前は無しでコンストラクタ呼んだ後がダメなら無理でしょ

インスタンス作って返すファクトリメソッドでも作れば?
0009以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:06:18.386ID:Inx+y79f0
>>7
なぜ
コンストラクタで例外投げるのは初期化中に例外投げるわけだけど
0010以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:06:57.199ID:Jxntdmw7M
constじゃなくてリテラル返す関数にすれば良くね
virtualでオーバーライドできるし、プリプロセスタイミングやコンパイルタイミングでチェックはconstexprとかつけてない限りはされんはず
0011以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:11:59.532ID:rePCrRO50
chatGPTの回答

はい、可能です。コンストラクタ内で条件チェックを行い、不正な場合は例外を投げることができます。例えば次のような実装が考えられます。

Range::Range(int from, int to) : from(from), to(to)
{
if (from >= to) {
throw std::invalid_argument("'from' must be less than 'to'");
}
}

このようにして例外を投げることで、不正な引数が渡された場合に適切に対処することができます。

C++の構文しらんから正しいかわからんけど
0012以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:15:42.464ID:GHcAe7Jg0
GPTちゃんしゅごい
0013以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:17:03.264ID:VLCsyyom0
class Range
{
public:
Range(float from, float to);
const float from;
const float to;

float checkFrom(float from, float to);
}

Range::Range(float from, float to) : from(checkFrom(from, to)), to(to)
{
};

一応こんな感じでできるか…
なんか不恰好な気がするけどもっと良い方法無いかな
0014以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:17:36.345ID:VLCsyyom0
>>11
いやそれチェックする前に初期化終わってるんよ
0015以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:18:31.990ID:n09FGh2O0
初期化しないってどういうこと?メモリアドレスが固定なの?
0016以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:20:48.282ID:VLCsyyom0
>>15
初期化しないんじゃなくて例外を投げるなら初期化前に投げたいって話
0017以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:21:04.882ID:wVpIqItD0
そもそもなんで初期化しちゃいけないんだよ死ね
0018以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:23:54.273ID:VLCsyyom0
>>17
>>1で挙げた例はメンバがfloatだからほぼ関係無いんだけどこれがfloatではなく初期化処理自体が重たいクラスだった場合に、コンストラクタの引数が不正ならその重たい初期化処理を走らせる前にさっさと例外を投げたい、みたいな感じ
0019以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:24:49.112ID:X7Ldh1uD0
外部でチェックしろよ
0020以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:26:35.717ID:VLCsyyom0
>>19
コンストラクタに渡せる条件の確認だからそのクラス自身に責任を持たせたい
0021以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:27:00.074ID:wVpIqItD0
なんで本来想定してるコード書かずにfloatで書いたの?
重くなるコンストラクタの例を書けよ
0022以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:30:01.504ID:n09FGh2O0
>>16
コンストラクタのラッパー関数用意すればいいって話かな
0023以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:31:23.007ID:wVpIqItD0
そのクラスのstaticメソッドでcreateInstanceみたいなの作れ
0024以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:31:46.013ID:wVpIqItD0
そんで更にnew禁止しろ
たしか方法あったはず
0025以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:33:01.443ID:VLCsyyom0
>>22
うーんそれだと結局外部でチェックすることになるけどまあそれが無難なのかなぁ
さっきのファクトリメソッド作れってレスの考えだね
0026以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:34:02.975ID:Ewhvs7/H0
class RangeBase
{
public:
RangeBase(int from, int to); //ここでチェックして例外投げる
}

class Range : Public RangeBase
{
public:
Range(int from, int to); //最初にRangeBase(from, to); 呼ぶ
const float from;
const float to;
}
0027以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:34:54.084ID:n09FGh2O0
>>25
メモリリークしないように例外投げればいけるんかな
0028以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:36:53.662ID:VLCsyyom0
>>23
なるほど、インスタンス生成関数をクラス自身に持たせる発想か
それ結構良いかも
0029以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:38:42.812ID:rePCrRO50
シングルトンでググって
0030以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:39:16.501ID:wVpIqItD0
シングルトンは関係無いでしょ
0031以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:40:22.696ID:rePCrRO50
コンストラクタをprivateにしてインスンス生成用staticメソッドを用意するところまでは同じでしょ
0032以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:40:41.143ID:VLCsyyom0
>>26
おおおお基底クラスのコンストラクタを利用するのか、なるほど
リスコフ置換原則に反してはいるけど面白い
全く思い付かなかった
0033以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:45:01.639ID:c8DPZFMl0
なんでメンバ変数にconst?
気になった
0034以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:46:26.979ID:VLCsyyom0
>>33
普通に変更しないからconst
0036以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:47:40.064ID:eZz1JgXt0
>>33
const無かったら生成時のvalidation無駄じゃん
0037以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:47:41.986ID:VLCsyyom0
>>26で思い付いたけど引数違いのコンストラクタを定義してもいけそう
ダミーの引数付けることになるが
0038以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:48:48.164ID:VLCsyyom0
>>35
上手くいくのは間違いないと思う
0039以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:53:15.763ID:c8DPZFMl0
>>34
単純にロジックで上書き弾いちゃえば?
大量生成しないなら速度も落ちないよ
もし勉強のためにconstで縛り入れてたらすまんな
0040以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 20:58:20.847ID:c8DPZFMl0
>>39
すまん取り消す
上書きじゃなくて大小比較か……
しかもコンストラクタでやらないといけないのか
だから例外出すしか無いのか
0041以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/02/09(木) 21:06:09.928ID:VLCsyyom0
>>23だとこんな感じか

class Range
{
private:
Range(float from, float to) : from(from), to(to) {};

public:
static Range createInstance(float from, float to)
{
check(from, to);
return Range(from, to);
}

public:
const float from;
const float to;

private:
static void check(float from, float to)
{
if (!from < to) throw std::exception("from < to is not satisfied.");
}
};
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況