2ちゃんねる ■掲示板に戻る■ 全部 1- 最新50    

0からの、超初心者C++相談室

1 :デフォルトの名無しさん:2018/11/12(月) 14:55:13.35 ID:Tf74ZWQr.net
何にも知らない0からの出発、超初心者のためのC++相談室

463 :はちみつ餃子 :2023/06/04(日) 09:37:21.42 ID:MHoxWKtY.net
>>461
std::stod は std::string と std::wstring に対応してるよ。

464 :デフォルトの名無しさん:2023/06/04(日) 09:39:47.38 ID:5jvZ+YKl.net
>>463
std::stod()は数値への変換が行われなかったとき例外をスローするが
後ろに余計なものが付いていたらスルーするんじゃ……
なお試したことはありま栓、

465 :はちみつ餃子 :2023/06/04(日) 09:52:59.20 ID:MHoxWKtY.net
>>464
???
それで何か困ることがあるという話なの?
要件が不明瞭でよくわからん。

466 :デフォルトの名無しさん:2023/06/04(日) 09:55:13.77 ID:5jvZ+YKl.net
実は正規表現でも使えば何とかなる……
のか……
std::regex re("^\s*([\d.]+)\s*$");
std::smatch m;
if (std::regex_match(str, m, re)) {
 return m[1].str().strtod();
} else {
 エラー
}


 

467 :デフォルトの名無しさん:2023/06/04(日) 09:56:15.54 ID:5jvZ+YKl.net
>>465
仕様は最初に提示stkr、
123.456E+8 : OK
123.456E+8a : NG

468 :はちみつ餃子 :2023/06/04(日) 10:00:50.19 ID:MHoxWKtY.net
>>467
続くものが何であるかは自分で確認してエラーにするという話をしてると思ったんやが。

469 :デフォルトの名無しさん:2023/06/04(日) 10:05:01.33 ID:5jvZ+YKl.net
>>468
>続くものが何であるかは自分で確認してエラーにする
・できればライブラリでやってホスイ
・自分で書くとしてもナマポ(&(str[0]))は避けたい(>>461
・std::string部分が他の文字列型に変わっても大丈夫なサポートがあるならそれに乗っかりたい手でテンプレートを書きたくない(>>461

できるかできないかで言えば、std::stringについてはダチャくあっても実現できてはいるので
C++でちょう簡潔に書ける手段が実はあるのではないか、ありませんか、というのが質問の意図

470 :はちみつ餃子 :2023/06/04(日) 10:13:13.65 ID:MHoxWKtY.net
>>469
続くものの種類で判断するというピンポイントな要求にマッチするものはさすがに標準にあるわけない。
それを除けば std::stod が十分に要求を満たしているように見える。

471 :デフォルトの名無しさん:2023/06/04(日) 11:40:09.61 ID:bxWaSYac.net
単位でも確認したいの?
だったらstd::ends_withとかstd::rfindとstd::substrで数字の後ろ切り出すとかでチェックしてからstd::stodでよくね
チェックは自分の要件だから自分で書け標準ライブラリはお前のお母さんではない

472 :デフォルトの名無しさん:2023/06/04(日) 11:51:26.73 ID:xmEQJDCs.net
正規表現でチェックするのが1番自然な気がする

473 :デフォルトの名無しさん:2023/06/04(日) 22:03:06.86 ID:5jvZ+YKl.net
>>471
> 単位でも確認したいの?
> だったらstd::ends_withとかstd::rfindとstd::substrで数字の後ろ切り出すとかでチェックしてからstd::stodでよくね
std::stringに格納された数値文字列を数値にしたい、
しかし数値以外の文字(ただし空白文字は認める)が後ろにくっついていたらエラーにしたい(>>459

> チェックは自分の要件だから自分で書け標準ライブラリはお前のお母さんではない
チェックのためには(例えばstd::stodが)どこまで読んだのかの情報が要る
std::stodの裏側では文字列を数値解釈する枯れたコードが動いているわけで、
そいつにどこまで読んだのか、ただ1個の整数データを聞けさえすれば良い。
これはそれほど無茶な話ではないはずで実際strtod()ではできるから
どっちかというtライブラリにちょっち不備があるのでは案件であってお母さん案件ではない。

474 :デフォルトの名無しさん:2023/06/04(日) 22:20:35.13 ID:5jvZ+YKl.net
>>472
上に書いた通り(例えば)std::stodがどこまで読んだのかだけイブラリが返してくれさえしたら解決するのじゃ
正規表現は意味的には合目的的な手段やが、普通の正規表現エンジンの実装なら正規表現オブジェクトを作った際に
FSMを(表形式か何かで)生成する処理が中で動くので、そんなに軽い処理ではないからやっぱ牛刀感みある…

いったん作ったらマッチングは表駆動でやれるので速いことが気体できるのではないか、という香具師が居るかもしれないが、
実はstd::stod()に最大限仕事させたい(正規表現の側で数値文字列の書式についてわざわざ指定したっくない
場合は>>496の正規表現は正しくは "^\\s*(.*?)\s*$"にせねばならないからマッチング時にバックトラックが発生して遅い可能性がある
これもちょっちイヤソな理由

繰り返しになるが(例えば)std::stodがどこまで読んだのかだけイブラリが返してくれさえしたらこんな考慮は不要で完全に円満に解決するのじゃ……

475 :デフォルトの名無しさん:2023/06/04(日) 22:30:29.50 ID:bxWaSYac.net
>>473
そんな長文ギャンギャン書きなぐってる暇があればstodの仕様くらい調べろよ
ちゃんとお前の欲しがってる物を返してくれるよ

476 :デフォルトの名無しさん:2023/06/05(月) 00:32:44.63 ID:8dockxGx.net
便乗質問していいですか
某所で似たような問題があったのだけど、付加条件として、数値がINT_MAXを超える場合は
INT_MAX、INT_MINを下回る場合はINT_MINを返す、がありました
stodを使う場合(stoll等でもいいですが)、これってどうやって処理すればいいですかね

477 :デフォルトの名無しさん:2023/06/05(月) 00:38:04.95 ID:8dockxGx.net
念の為「数値が」というのは元の文字列での、です。たとえば "1000000000000"みたいな
可能性としてはLONG_LONG_MAXを超えている場合もありますね

478 :デフォルトの名無しさん:2023/06/05(月) 00:46:19.80 ID:oX+QCkCh.net
stoi系は範囲越えたらstd::out_of_rangeを投げるはずだが

479 :デフォルトの名無しさん:2023/06/05(月) 01:19:48.15 ID:8dockxGx.net
_MAXで超えたか_MINで超えたかってわかりますかね

480 :デフォルトの名無しさん:2023/06/05(月) 01:31:31.21 ID:oX+QCkCh.net
先頭文字が'-'かどうか見れば?

481 :デフォルトの名無しさん:2023/06/05(月) 01:54:42.53 ID:yTJt/rkc.net
>>475
どういうこっちゃkwsk、

482 :デフォルトの名無しさん:2023/06/05(月) 02:04:38.53 ID:LZnxgWkc.net
>>481
https://ja.cppreference.com/w/cpp/string/basic_string/stof

> pos がヌルポインタでなければ、ポインタ ptr (変換関数の内部的な変数) が str.c_str() 内の最初の変換されなかった文字のアドレスを受け取り、その文字のインデックスが計算されて *pos に格納されます。 これは変換によって処理された文字数になります。

> 引数
> str - 変換する文字列
> pos - 処理された文字数を格納する整数のアドレス

483 :デフォルトの名無しさん:2023/06/05(月) 02:37:23.50 ID:yTJt/rkc.net
>>482
㌧クスわかりたorz

484 :デフォルトの名無しさん:2023/06/05(月) 06:49:34.05 ID:8dockxGx.net
>>480
そうですね、でも文字列の先頭とは限らないですよね。やはりこの場合はある程度は
自力で文字列をパースする必要がある感じですかね

ちなみに数字以外が含まれるときの挙動は "hoge 123"みたいに数字より前に非数字
がくるのは駄目だけど逆に"123 hoge"みたいのはおkなんですね

485 :デフォルトの名無しさん:2023/06/20(火) 19:02:06.99 ID:mbwsU8Mq.net
話題がないから質問してみる

struct Summer {};
Summer summer;
Summer *const summerConstPtr{};
const_cast<Summer*>(summerConstPtr) = &summer; // だめ
const_cast<Summer*&>(summerConstPtr) = &summer; // いける

質問1) 最後のいけるやつのconst_cast<Summer*&>の「&」はどういう意味なんでしょう? 参照のことかいな?
質問2) なんでconst_cast<Summer*>ではだめなのかな?

486 :デフォルトの名無しさん:2023/06/20(火) 19:05:08.72 ID:mbwsU8Mq.net
なんか変換されたw
∑merでなくて&summerです

487 :はちみつ餃子 ◆8X2XSCHEME :2023/06/20(火) 20:45:04.07 ID:IIzrqfbq.net
>>485
参照が絡むとややこしくて単純に説明できないんだけど
代入演算子の左側は変更可能な lvalue (modifiable lvalue) であることということになっていて
そのキャストだと prvalue になってしまうから代入できないという結果になる。

たとえば
int x = 1;
x = 2;
は有りだけど
1 = 2;
は駄目なのはわかるでしょ。

この代入のときの x はそこに入っている 1 という値に意味はなくて場所に意味がある。
値として取り出されてしまうと代入できないんだ。

488 :はちみつ餃子 ◆8X2XSCHEME :2023/06/20(火) 20:54:10.99 ID:IIzrqfbq.net
どういうときにどういう値カテゴリに属すことになるのか正確なところはここ見て。
https://timsong-cpp.github.io/cppwp/n3337/basic.lval

C++03 時代は lvalue と rvalue だけの単純な (と言ってもそれなりに複雑だが……) 世界だったんだけど
右辺値参照の概念を整理するため (?) かだいぶんごちゃついてる。

489 :デフォルトの名無しさん:2023/06/20(火) 23:48:13.65 ID:mbwsU8Mq.net
>>487
返答ありがとう。

なぜconst_cast<Summer*>(summerConstPtr)が左辺としていけないのかがわかりませぬ。
summerConstPtrはconst_cast<Summer*>によって「Summer *const」から「const」が外れて「Summer*」となって
Summer *summerPtr;
summerPtr = &summer;
とするときの左辺summerPtrと同じようになったわけではないのでしょうか?

どうもこの左辺summerPtrと同じようにするためには、const_cast<Summer*&>としなければならないようだが、この「&」にはどんな意味ががが??

490 :はちみつ餃子 ◆8X2XSCHEME :2023/06/21(水) 00:33:00.36 ID:3HBFHOpK.net
>>489
型とは別に (型と無関係ではないが) 文脈にカテゴリが存在するというのが肝心な部分。
どれがどのカテゴリに属すのかはダラダラとした箇条書きで書いてあって単純な原則では示せない。
(結果的には辻褄の合うようになってるけど……。)

& は参照を表す記号という解釈は正しい。
参照は lvalue なのでキャストの結果も lvalue ってだけ。

491 :デフォルトの名無しさん:2023/06/21(水) 01:03:31.08 ID:tILY3YM/.net
>>489
その理解だと↓も通ることになると思うんだけど、これが通らない理由もわからない?
int i = 0;
static_cast<int>(i) = 1;

492 :デフォルトの名無しさん:2023/06/21(水) 11:05:32.10 ID:cZp0PZIW.net
>>490,491
「&」はやはり参照でしたか。
左辺の規則と右辺の規則があり、キャストしたポインターでは左辺の規則に従ってなくて、キャストした参照なら左辺の規則に従っていると、そうなっていると覚えるほかないのでありますな。
ありがとう。

493 :デフォルトの名無しさん:2023/06/29(木) 00:53:29.69 ID:l197jz/x.net
なんで可変長配列の名前がvectorなの?

494 :はちみつ餃子 ◆8X2XSCHEME :2023/06/29(木) 08:14:12.68 ID:l+ZsGqGg.net
伝統。

495 :デフォルトの名無しさん:2023/06/29(木) 13:14:41.30 ID:DfwcYShQ.net
https://www.google.co.jp/search?q=%E3%83%99%E3%82%AF%E3%83%88%E3%83%AB+%E6%84%8F%E5%91%B3
向きを持つ量をベクトルという
向きを持つためには複数の量が必要(単一の量はスカラーという)
それを抽象化して、要素を一列に並べたものをベクトルという

496 :デフォルトの名無しさん:2023/07/04(火) 17:43:58.34 ID:Ld2RSFGK.net
c++に限定される疑問ではないかも知れませんが標準出力がどうやってコンソールに出力しているか?というところで躓いてます
gnuのlibcを見てもわからず、アセンブラを見て0x80というシステムコールをしているところまで辿り着いたけど無学なので理解できずにいます
OSが用意している機能を実行しているという認識であってますか?

497 :はちみつ餃子 ◆8X2XSCHEME :2023/07/04(火) 17:52:47.39 ID:wwaI/oJF.net
>>496
そうだよ。
現代の OS は権限の管理がしっかりしてて、アプリケーションは
プロセスの外のリソース (メモリやデバイス) を直接には使えない。
OS に要求して適当なところに橋渡ししてもらう構造。

498 :デフォルトの名無しさん:2023/07/04(火) 18:05:29.71 ID:Ld2RSFGK.net
>>497
どうやって実行中のコンソールに出力しているのだろうという素朴な疑問だったのですが、この先はOS仕事という事なんですね
自分で見ろって言われるかもしれませんが、OSの処理の実装を見るのは難易度高いですか?
HelloWorldからどちらに進もうか迷ってます

499 :デフォルトの名無しさん:2023/07/04(火) 19:16:32.21 ID:Ld2RSFGK.net
同様のテーマのITmediaの記事を見つけたので腰を据えて取り組んでみようと思います
回答いただきありがとうございましたお騒がせしました

500 :はちみつ餃子 ◆8X2XSCHEME :2023/07/05(水) 00:40:03.93 ID:h//lr2GB.net
>>498
標準出力の実態はパイプ。
パイプの接続先がターミナルのプロセスが繋がってるだけでカーネルはそれほど大したことはやってない。

と言えれば簡単なんだけど端末制御まわりは歴史的事情でよくわからんことになってるので
ソースコードだけから読み取ろうとするのはしんどいと思う。

501 :デフォルトの名無しさん:2023/07/13(木) 01:46:39.34 ID:a7xsv8mg.net
shared_ptrの解放時にweak_ptrを登録していたSTLコンテナから登録抹消したいけど、
shared_ptrのデリータでshared_ptr自身は扱えないっぽい。
出来ないということは、何か他にいい方法があるか、根本的に何か考え方間違ってる?

502 :はちみつ餃子 ◆8X2XSCHEME :2023/07/13(木) 18:07:22.25 ID:46c6OBqO.net
>>501

設計意図次第だけど
コンテナにはオブジェクト本体をいれて shared_ptr は
コンテナ内の要素を指すイテレータを指す
という構造はどうだろう。

#include <iostream>
#include <memory>
#include <set>

int main(void) {
std::set<int> container;
auto [iter, result] = container.emplace(42);
{
// コンテナ内の要素を指す shared_ptr をいくつも作る
auto x = std::shared_ptr<decltype(iter)>(new decltype(container)::iterator(iter), [&container](decltype(container)::iterator* p) { container.erase(*p); delete p;});
auto y = x;
auto z = x;
// コンテナの中には要素が入ってる
for (auto& x : container) std::cout << x << " ";
std::cout << std::endl;
// shared_ptr はここで消滅
}
// デリータが消したのでもう残ってない
for (auto& x : container) std::cout << x << std::endl;
}

503 :デフォルトの名無しさん:2023/07/13(木) 21:30:08.90 ID:BEK5Ztwm.net
>>502 ありがとうございます。実体とイテレータ、参考になります。
おかげで解放時何とかshared_ptrで引数を渡そうとしてましたが、諦めて実体でもいいんではと思い始めました。
回答を見るまでは、shared_ptr<shared_ptr<X>>なら解放時にshared_ptr<X>取れるじゃん、
修正とか色々めんどくさいけど、とかアホなこと考えてました。

処理の概略はshared_ptr側で値管理、コンテナ側は登録されたweak_ptrの値と別の値が合致したら処理、
shared_ptr側解放時コンテナ側から登録抹消(抹消関数の引数にshared_ptr:これがNG)というものです。

504 :デフォルトの名無しさん:2023/07/16(日) 13:37:45.84 ID:aonKa36p.net
設計意図次第

505 :504:2023/07/16(日) 21:29:25.31 ID:AcIm+utR.net
何でかshared_ptrって派生出来ないと思い込んでたけど出来た。
shared_ptrで出来ない理由は分からんが、他に変な問題が無ければほぼ当初の想定通り。
ありがとうありがとう。

template<class T>
struct X : public std::shared_ptr<T> {
X(T* t) : std::shared_ptr<T>(t){}
~X(){/*X自体の登録抹消*/}
};

506 :蟻人間 ◆T6xkBnTXz7B0 :2023/07/16(日) 22:10:43.92 ID:/+p/BpGt.net
クラス内部で
using std::shared_ptr<T>;
を付けるとコンストラクタの実装が完璧になるよ。

507 :蟻人間 ◆T6xkBnTXz7B0 :2023/07/16(日) 22:12:03.59 ID:/+p/BpGt.net
>>506
クラス内部で
using std::shared_ptr<T>::shared_ptr;
を付けるとコンストラクタの実装が完璧になるよ。

508 :504:2023/07/16(日) 22:37:21.87 ID:AcIm+utR.net
>>507 基底クラス(shared_ptr)のコンストラクタを派生側に引っ張って来る便利な奴ですね(覚えきれてない)。
ありがとうございます。自前実装不要なのは助かります。

509 :はちみつ餃子 ◆8X2XSCHEME :2023/07/17(月) 00:18:57.61 ID:YifLUjyU.net
>>505
それって本当に意図通り?
X のデストラクタが起動するのは X 型のオブジェクトが解体されるときであって
参照カウントがゼロになったときじゃないんだよ。

510 :504:2023/07/17(月) 01:33:58.67 ID:9b8iHtwy.net
>>509 …あー。それは意図通りではないですね。実際の解放はデストラクタで
use_count()==1であることを確認する必要があるのかな。ありがとうございます。

511 :はちみつ餃子 ◆8X2XSCHEME :2023/07/18(火) 09:19:59.88 ID://OyAtPF.net
パブリック継承した型では基底への型変換を禁じることができない。
つまり
X<int> foo = new int(1);
std::shared_ptr<int> bar = foo;
みたいなことが出来てしまう。

間違った使い方を想定するとキリがないから
なんでもかんでもガチガチに型を設計する必要はないんだけど、
この場合はどこかでミスりそうと思うので
私なら継承でスマートポインタの挙動をカスタマイズしようとはしないと思う。

512 :504:2023/07/19(水) 03:16:45.39 ID:0uGQJSD8.net
>>511
御忠告ありがとうございます。
高々shared_ptr自身を解放するだけと思っていたんですが、色々難しいですね。

> パブリック継承した型では基底への型変換を禁じることができない。
そんな問題があるとは。
派生クラスのキャスト演算子は引っかからず、基底クラスの
コピーコンストラクタをいじらないと禁止出来ないっぽかった。
protected継承にしてみたら代入は出来なかった。うーん、他に問題が無ければこれですかね。

> 間違った使い方を想定するとキリがないから
> なんでもかんでもガチガチに型を設計する必要はないんだけど、
> この場合はどこかでミスりそうと思うので
> 私なら継承でスマートポインタの挙動をカスタマイズしようとはしないと思う。
候補はprotected継承(暫定)、shared_ptr相当自作、或いは他の未知なる何か。
しかし一番素直で的確に機能を実現可能と思っているのがshared_ptrの拡張なので、
別の形で実現する方法はどうも迂遠過ぎて自分には思いつかないです。
# shared_ptr側がデータ実体と登録したコンテナの情報を持ち、コンテナ側はweak_ptrで参照
なので流石に自作は無し、とりあえず他に致命的な問題が無ければprotected継承で実装して、
他により良い方法を思いついたらそっちに乗り換えることにします。

513 :504:2023/07/19(水) 18:45:15.41 ID:4lyHW67x.net
そういえばweak_ptr試してない…?と思って試したら当然の如く代入できなかったので、
public継承でほったらかします。

514 :デフォルトの名無しさん:2023/07/20(木) 15:28:07.42 ID:6BSTmMYa.net
templateの世界へようこそ

515 :はちみつ餃子 ◆8X2XSCHEME :2023/07/21(金) 13:23:19.14 ID:NiBubQrd.net
std::unique_ptr なら型引数でもデリータを与えることが出来て、
型引数が異なれば異なる型ということになる。

#include <memory>
template<class T> struct custom_delete : public default_delete<T> {};

int main(void) {
std::unique_ptr<int, custom_delete<int>> foo{new int(42)};
// ↓ 別の型なので移動できない。 エラーになる。
std::unique_ptr<int> bar = std::move(foo);
}

ところが std::shared_ptr では型引数でデリータをカスタマイズすることが出来ない。
解体は動的な型に従うという保証をしているので。

#include <memory>
struct foo {};
struct bar : public foo {};

int main(void) {
// 解体のときに foo ではなく bar の
// デストラクタが呼ばれることが保証される
std::shared_ptr<foo> x{new bar};
}

std::shared_ptr は動的な情報 (実行時の情報) を元に挙動が決まるというのが
設計理念なので削除方法をカスタマイズしたいならコンストラクタにデリータを渡す
というのが最も自然な形と言える。

std::shared_ptr を継承する形でカスタマイズしようとするのは
してもそれ自体は仕様に反しないけれど不自然だなぁとは思う。 (個人の感想です。)

516 :504:2023/07/21(金) 20:08:15.21 ID:jaEOXewl.net
一応発端の動かなかったコードを短くしたのでおいときます。
0.動機:shared_ptr<int>のdeleterでvector<weak_ptr>を削除したい
1.deleter内だとxは有効でuse_count 0だったけど、vectorのweak_ptrは無効だったのでvectorから削除できない。
2.shared_ptr<int>のデリータはint*に対するもので、shared_ptr<int>へのポインタはshared_ptr<int>の
デストラクタじゃないと処理できないけど、既製品だから外からいじられない。
3.んじゃ、手っ取り早くshared_ptr継承してデストラクタを使えるようにすれば?
というのが趣旨でした。

#include<vector>
#include<memory>
int main(){
std::vector<std::weak_ptr<int>> v;
std::shared_ptr<int> x(new int(3), [&x, &v](int* i){
for(int j = 0; j < v.size(); j++){
std::shared_ptr<int> t = v[j].lock();
if(t && t == x){v.erase(v.begin() + j); break;}
}
delete i;
});
v.push_back(x);
}

517 :デフォルトの名無しさん:2023/07/25(火) 09:24:45.92 ID:k8WJtY+U.net
>shared_ptr<int>へのポインタはshared_ptr<int>のデストラクタじゃないと処理できない

これが無理っしょ

518 :デフォルトの名無しさん:2023/07/28(金) 10:56:39.59 ID:Zgvcm9f5.net
なんで出来ると思ったの

519 :デフォルトの名無しさん:2023/07/29(土) 20:15:59.76 ID:ETnyq2kJ.net
shared_ptrのデリータで他所様のオブジェクトもついでに解体したろっていう発想そのものが危険な香りしかしなくてゾワゾワする

520 :デフォルトの名無しさん:2023/07/29(土) 20:25:36.66 ID:xEb8mTKO.net
シャー専用ptr

521 :1:2023/09/03(日) 20:55:45.58 ID:/ExZEMtW.net
「プログラム」作るのって、やってみたいけど、全然知らないから、教えて欲しい。
からのスレの目的で建てました。

522 :デフォルトの名無しさん:2023/09/03(日) 20:59:12.95 ID:W287fTtw.net
まず、何が作りたいかイメージしてみましょう

523 :デフォルトの名無しさん:2023/09/04(月) 10:11:49.98 ID:/ASAZOX6.net
>>521 がC++をやるのは早過ぎる
先にpythonでもやってみろ

524 :デフォルトの名無しさん:2023/10/02(月) 22:07:14.88 ID:l4Vvzubd.net
次のプログラムを実行するとコメントのように出力がされ、mainの最後で例外が発生してしまいます。
なぜ例外が発生するかわかる方教えてください。
mainを通してnewは2回実行され、deleteも2回実行されるので空ポインタをdeleteしていることもないと思うのです。
#include <iostream>
using namespace std;
class Csmp1 {
private:
int x;
int* p;
public:
Csmp1(int n);
~Csmp1();
void disp() { cout << "x=" << x << endl;}
};
Csmp1::Csmp1(int n) {
x = n;
p = new int;
cout << "constructor " << x << endl;
}
Csmp1::~Csmp1() {
delete p;
cout << "destructor " << x << endl;
}
int main()
{
Csmp1 d3(300); // "constructor 300"と出力
d3.disp(); // "x=300"と出力
d3 = Csmp1(400); // "constructor 400"と出力し、その後"destructor 400"と出力
d3.disp(); // x=400と出力
return 0;
} // デストラクタが呼ばれ、delete の部分で"Unknowin signal"例外発生

525 :蟻人間 ◆T6xkBnTXz7B0 :2023/10/02(月) 22:12:06.36 ID:/sjCb2h4.net
>>524
d3 への代入で暗黙のコピーコンストラクタが使われている。コピーコンストラクタを適切に定義すれば解决する。

526 :蟻人間 ◆T6xkBnTXz7B0 :2023/10/02(月) 22:12:09.92 ID:/sjCb2h4.net
>>524
d3 への代入で暗黙のコピーコンストラクタが使われている。コピーコンストラクタを適切に定義すれば解决する。

527 :蟻人間 ◆T6xkBnTXz7B0 :2023/10/02(月) 22:12:23.61 ID:/sjCb2h4.net
>>524
d3 への代入で暗黙のコピーコンストラクタが使われている。コピーコンストラクタを適切に定義すれば解决する。

528 :蟻人間 ◆T6xkBnTXz7B0 :2023/10/02(月) 22:12:42.13 ID:/sjCb2h4.net
>>524
d3 への代入で暗黙のコピーコンストラクタが使われている。コピーコンストラクタを適切に定義すれば解决する。

529 :蟻人間 ◆T6xkBnTXz7B0 :2023/10/02(月) 22:18:32.15 ID:/sjCb2h4.net
連投すみません。コピーコンストラクタと、代入もです。

530 :はちみつ餃子 ◆8X2XSCHEME :2023/10/03(火) 00:13:21.44 ID:OUiDjLFt.net
>>524
暗黙に生成される代入演算子は全てのサブオブジェクトを代入したような挙動になるルール。

ポインタを代入した場合には代入元と代入先のポインタが指す先のオブジェクトは同一なので
一方のポインタを通じて delete したならもう一方のポインタからオブジェクトに触れようとしてはならない。
(もう存在しないので。)

この場合は
d3 = Csmp1(400);
としたときに生成される一時オブジェクトはこの式が終わった時点で解体されるので
d3 内にあるポインタはデストラクタで delete 済み、すなわち無効なポインタとなる。
d3 のデストラクタが起動したときはデータメンバ p が指している先は無効なので
無効なポインタをいじったことになって問題が生じる。

それと d3 のコンストラクトのときに new したオブジェクトはどこからも delete されてない。

531 :527:2023/10/03(火) 00:55:04.57 ID:RKQFDOr6.net
>>529-530
お二人さま ありがとうございます。

>d3 = Csmp1(400);としたときに生成される一時オブジェクトはこの式が終わった時点で解体される

右辺により生成されるオブジェクトが単にd3に格納されるのではないのですか。
それと入れ替わりに、d3コンストラクト時のオブジェクトのデストラクタが呼ばれると思ってました。
(どこからも参照されなくなるので)

自分が根本的に誤っている気がします、すみませんが上の内容でおかしい点を教えてください。

532 :はちみつ餃子 ◆8X2XSCHEME :2023/10/03(火) 02:13:14.63 ID:OUiDjLFt.net
>>531
> 右辺により生成されるオブジェクトが単にd3に格納

JavaScript とか Python の動的型言語の経験があるのかな?
それとも Java や C# の参照型のモデルで考えてる?

C++ では左辺はメモリ上の特定の場所に対応づいていて、
別の場所 (右辺で生成される一時オブジェクト) にあるものを格納するというのは
コピーするということ。

その上で不要になった一時オブジェクトは解体される。
一時オブジェクトは一部の例外を除いて完結式 (完全式ということもある) の終わりのタイミングで
解体されるルールなのでこの場合は行の終わりが解体のタイミングということになる。

533 :はちみつ餃子 ◆8X2XSCHEME :2023/10/03(火) 02:13:25.78 ID:OUiDjLFt.net
>>531
> 右辺により生成されるオブジェクトが単にd3に格納

JavaScript とか Python の動的型言語の経験があるのかな?
それとも Java や C# の参照型のモデルで考えてる?

C++ では左辺はメモリ上の特定の場所に対応づいていて、
別の場所 (右辺で生成される一時オブジェクト) にあるものを格納するというのは
コピーするということ。

その上で不要になった一時オブジェクトは解体される。
一時オブジェクトは一部の例外を除いて完結式 (完全式ということもある) の終わりのタイミングで
解体されるルールなのでこの場合は行の終わりが解体のタイミングということになる。

534 :はちみつ餃子 ◆8X2XSCHEME :2023/10/03(火) 02:17:47.16 ID:OUiDjLFt.net
サーバから書込みエラーが返ってきたのを専ブラの機能でリトライしたら多重投稿になってしまってるな。
なんか不安定な状況っぽい

535 :デフォルトの名無しさん:2023/10/05(木) 17:15:14.18 ID:WXXGTjkD.net
みんなでリトライするからF5攻撃並みに自爆DOS攻撃

536 :デフォルトの名無しさん:2023/10/05(木) 18:29:28.73 ID:S7K0dlIY.net
>>524
int *をunique_ptr <int>にすると
コンパイルで弾かれるから
気づきやすいかもね
newとdeleteは直で呼ばない方が良い

537 :デフォルトの名無しさん:2023/10/06(金) 10:09:01.67 ID:Zl0hPCVy.net
newとdeleteを直で呼んでるかどうかと
今回の問題(コピーが発生してるかどうか)は
関係無いんじゃね?

538 :デフォルトの名無しさん:2023/10/06(金) 10:16:23.02 ID:QFTcWZUD.net
いきなりC++から入るとは…
考え直した方がいい

539 :デフォルトの名無しさん:2023/10/06(金) 12:08:09.60 ID:xj8n2YWF.net
>>537
「コピーが発生してるかどうか」とは関係ないのはその通り
>>524が恐ろしいのは
コンパイル時点では気づかず実行して初めて明らかになるところ
どうしたら実行前に避けるかの方策として
unique_ptrの常用を提案しました

540 :デフォルトの名無しさん:2023/10/06(金) 13:16:53.99 ID:Zl0hPCVy.net
>>524 に有効な解決策は
コピーコンストラクタじゃなくて
ムーブコンストラクタじゃないのかな

541 :はちみつ餃子 ◆8X2XSCHEME :2023/10/06(金) 16:48:00.89 ID:R7EjAYTn.net
両方やっとけばええじゃろ。

542 :デフォルトの名無しさん:2023/10/06(金) 21:05:50.93 ID:BgvqARb2.net
vector dp(N+1,vector(i+1,vector<mint>(i,0)));
これはdp[N+1][i+1][i]個のデータを確保していると思っておk?

543 :デフォルトの名無しさん:2023/10/06(金) 21:10:07.75 ID:G9Jlm58L.net
OK牧場!

544 :デフォルトの名無しさん:2023/10/06(金) 21:44:11.09 ID:BgvqARb2.net
TXH!

545 :527:2023/10/16(月) 23:49:47.91 ID:6sfjI2pS.net
>>532 を始めとして皆さんまたまたありがとうございます。
アセンブラ、Cを長くやってきたあと、最近C#を少し覚えたのでそちらと混同していました。

コピーコンストラクタと代入の演算子関数を作ろうとしていますがまだ途中。少しずつ進めます。

546 :デフォルトの名無しさん:2023/10/17(火) 23:09:31.94 ID:cH9YbrYr.net
既製品のクラスライブラリについて、クラス階層が深いところのクラスは、公開メンバの全体をひと目で見渡すことができません。
マニュアルや継承のツリーををたどって地道に調べるしかないのですか。

547 :はちみつ餃子 ◆8X2XSCHEME :2023/10/18(水) 09:51:20.64 ID:UZlHr99J.net
>>546
ソースコードの構造を調べるのを補助するツールはあるが
どういう意図でどういう使い方を想定してそう書かれているのかは
プログラマが読み解かないとどうしようもない。

548 :デフォルトの名無しさん:2023/10/18(水) 17:06:40.02 ID:d+gN3jrr.net
既製品ならドキュメントあるだろ
ドキュメントで謳ってないことはやるべきでない

549 :デフォルトの名無しさん:2023/10/18(水) 21:01:33.56 ID:XEk7oAP2.net
visual studio community 2022で、
他のソリューションで作成されたmoduleをimportする方法がわかりません。
#includeみたいにパスを指定する方法とかがあるんでしょうか?

550 :デフォルトの名無しさん:2023/10/18(水) 21:18:35.91 ID:GW9b62tt.net
あるよ

551 :デフォルトの名無しさん:2023/10/18(水) 22:46:30.83 ID:XEk7oAP2.net
>>550
ぜひ教えてください!

552 :デフォルトの名無しさん:2023/10/19(木) 10:07:14.52 ID:W1XtHktx.net
外部モジュール取り込みは言語仕様じゃ無くてIDEの機能だから

553 :デフォルトの名無しさん:2023/10/20(金) 09:56:30.99 ID:/M3RKJCH.net
IDEに頼ってるとアホになるよ

554 :デフォルトの名無しさん:2023/10/21(土) 16:32:35.29 ID:dhBJRkMq.net
0のうちにやめとけ
時間がもったいない

555 :デフォルトの名無しさん:2023/10/26(木) 23:16:10.15 ID:4gABazLN.net
typedef uint8_t byte;
:
byte a = 3;
uint8_t b = a;

bの初期化は型不一致エラーにならないと思います。

コンパイラは型の異なる変数の初期化や代入を見つけると、typedefを探して元の型が同一かを調べてエラーにするかどうかを決めるのですか。

556 :デフォルトの名無しさん:2023/10/26(木) 23:23:19.82 ID:oN20rU1J.net
>>555
typedef は型の別名を作る機能であって新しい型を作らない。

557 :デフォルトの名無しさん:2023/11/05(日) 12:44:18.01 ID:iVzKXsmj.net
Visual StudioでソリューションAでビルドしたブツ(.exe、.dll、lib)、シンボルファイル(.pdb)、必要なヘッダファイル(.h)
をソリューションBで取り込むの場合、Aのビルド後イベントとBのビルド前イベントを駆使してフォルダのパスは
"$(Solution)..\x\$(Platform)\$(Configuration)" みたいなマクロで解決、みたいなローテク頼みという印象、
Visual Studio 2019以降だと今は実はもっと簡単?

558 :デフォルトの名無しさん:2023/11/10(金) 23:40:20.59 ID:mtEH7OmF.net
class MyClass {
public:
MyClass();
:
};

int main()
{
MyClass* c = new MyClass(); ①
MyClass d;
MyClass* dp = &d; ②
:
}

オブジェクトのポインタは①や②のように取得できると思います。
私からすると①はdeleteしなければならないのでできれば使いたくない。

①の書き方は、よく入門書に出てくる、継承関係にあるポインタの相互代入のためにあると考えて正しいですか。

559 :デフォルトの名無しさん:2023/11/10(金) 23:49:08.54 ID:VDRR6isO.net
>>558
その「相互代入」って何ですか?

560 :はちみつ餃子 :2023/11/10(金) 23:56:43.46 ID:Irnop6+y.net
>>558
自動変数の寿命はスコープ単位だから
それより長い寿命のオブジェクトが必要なら new する。
寿命の種類のことを Storage duration といい、
new で生成したオブジェクトは Dynamic storage duration に該当する。

継承関係がどうこうというのは何が言いたいのかよくわからないが、
ポインタの性質はオブジェクトの寿命とは関係ない。

561 :デフォルトの名無しさん:2023/11/12(日) 00:13:49.90 ID:M40i1rJ9.net
相互代入は言葉がおかしいですね。
基底クラスのポインタで派生クラスのオブジェクトをポイントできるというものです。
オブジェクトのボインタを使う場面があまりないので用途を聞きました。

>>560
>自動変数の寿命はスコープ単位だから
それより長い寿命のオブジェクトが必要なら new する。

自分の場合、関数内より長い寿命が必要となったらそれはもうグローバルにしてしまいます。設計方針がよくないですかね。

562 :はちみつ餃子 :2023/11/12(日) 02:00:51.06 ID:O0gb6uIB.net
>>561
グローバル変数として書いたオブジェクトの寿命は static storage duration に該当する。
この static というやつは main が始まる前に構築されて main が終わった後に解体されるので
必要以上に長い寿命になってしまうことが多いし、
実行時の情報を元にして構築するオブジェクトを static にはしようがない。
dynamic (new でのオブジェクト生成) が必要になる場面はごく普通にある。
ごく普通にあるのに使わずに済ませてるならたぶん不自然な設計になってると思う。

グローバル変数は寿命も長すぎるがスコープも広すぎる。
人間は自分が思ってるより馬鹿だから最初にどういう想定をしてたのか忘れて要らんことをしてワヤにする。
触らせたくないものは隠しておくのはカプセル化の考え方の重要な部分。

本当に人間は忘れるし間違える。
部品ごとに間違った使い方を出来ないように配慮しておかないと規模を大きく出来ない。
まあ逆に言えば小さいプログラムではそんなに凝ったことをしなくても大丈夫なんだけど。

563 :デフォルトの名無しさん:2023/11/12(日) 11:04:18.35 ID:l8rhUXJt.net
>>558
>@の書き方は、よく入門書に出てくる、継承関係にあるポインタの相互代入のためにあると考えて正しいですか。
そのためだけにあるという訳ではない

>私からすると@はdeleteしなければならないのでできれば使いたくない。
生のポインタではなくスマートポインタ(unique_ptrやshared_ptr)を使えば
deleteはスマートポインタがやってくれる
構築は uniqu_ptr <MyClass> = new MyClass(); や
uniqu_ptr <MyClass> = make_unique <MyClass> (); のようにやる

297 KB
新着レスの表示

掲示板に戻る 全部 前100 次100 最新50
名前: E-mail (省略可) :

read.cgi ver.24052200