C++相談室 part131 [無断転載禁止]©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
次スレを立てる時は本文の1行目に以下を追加して下さい
!extend:on:vvvvv:1000:512
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。
前スレ
C++相談室 part130
http://mevius.2ch.net/test/read.cgi/tech/1490917669/
このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.100【環境依存OK】
http://echo.2ch.net/test/read.cgi/tech/1478440682/
■長いソースを貼るときはここへ。■
http://codepad.org/
https://ideone.com/
[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
-
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured >>471
この意見はさすがに論外だわ
ポインタは難しいものでもややこしいものでもないから、ちゃんとした読み物があれば問題なく理解できる
難しいなら後回しにしてもいいならわかるが、最初から教えないというのは学習の機会を奪っているとさえいえる >>443
はげどう
>>444
言語選ぼうよ;;
>>445
イテレータはポインタの概念を引きずってゐる
プログラムの動作を簡明に表すという意味では
配列の構文さえあれば十分なのに、
※ 個人の感想です 老害が多いな
ソフトをやるならアセンブラからとか言いそうな勢い 尤も、C++の配列とか要素型であるクラスの継承とか多態性を表現しきらん欠陥品ではあるのだが
(インターフェースの配列はポインタの配列としてやるしかない;;
それゆえにやっぱC++で入門するなら中身知っとけと、 >>475
あなたに教えを請う人がいれば、あなたが教えたいように教えたらいい >>478
STLはテンプレートライブラリだから、動的なポリモーフィズムにガッツリ対応してないのは当然だし、
そーいうのがほしけりゃ自分で書けばいいだけ >>480
左様動的なポリモーフィズムにガッツリ対応したコンテナクラスのテンプレートを
曲がりなりにもかけるようになってからがC++の入門編
抽象化された上位レイヤーの知識だけあれば詳細は知らなくて良い、というのは
漏れのない抽象化が達成された後のみ通用する話だが
ずんねんながらC++はそうではないし言語の性格上っ今後とも永遠にそうはならない >>471
その有益というrange-based forを説明してくれよ。 >>483
悪いが馬鹿老害は黙っててくれないか。
若い人がせっかく説明したほうが有益だと言ってくれてるのだから。他の人も賛同してくれてる。 >>464
いや、もちろん意識してるだろ。
そう書いたつもりだけど、どこをどう読んだんだ? >>471
おまえさ、じゃあ配列の添字は何だと思っているわけ?
「どこにある」という情報をもつもの、という点で同じだぞ
だから for(i = first ; i != last; ++i) において first や last や i が
整数であろうがポインタであろうがイテレータであろうが
同じ論理が通用するんだろうがよ
ポインタで範囲外アクセスこくような大馬鹿者が
整数ならそんなことないとでもぬかすのか? >>472
おまえC++やCよりも前に何かやってただろ
俺だってC++をCより先に憶えたクチで
そんな真似ができたのはアセンブラ使いだったからな
間接の概念をまっさらから憶えるのに
イテレータは無駄に難しいマゾプレーだつってんだ
ポインタわかっててもハンドルで悩むやついるくらいで
それに輪を掛けて++まであるのがイテレータであって >>471
まだ説明してないのか。説明頼むよ。キミが言い出したことなんだよ。 (void*以外の)ポインタ自体も生のアドレス概念からは抽象化されている。
指されるオブジェクトの型やサイズを持っているんだからね。
それをさらに(ある方向に)抽象化したものがイテレータなんであって、そのように段階を追って
抽象化されていくストーリーを語るのは初心者向けにも有意義だと考える。 イテレータに限らないけど抽象化されたものは抽象化されたままで扱わないと抽象化した意味がなくて、
(内部の実装を意識しなきゃならないのなら抽象化の甲斐が無い。)
一方では、その抽象化を作る側になることもあるので抽象化が出来上がるまでは抽象化の内側も知ってなきゃいけない。
つまり、層を積み重ねるたびに抽象化の壁を作っていくってのがプログラムを構成する基本的なやり方だろう。
だから、プリミティブな方から積み重ねながらその抽象化が意味するところを学ぶってのは普通の方法だと思う。
そういう意味で >>493 に賛成。
抽象化の内側を知ってしまった人が抽象化の壁の向こうを忘れて抽象化されたものとしてだけ
扱うってのはそれなりにセンスがいるんじゃないかとも思うんだけど、
C/C++ の背景にあるセマンティクスは良くも悪くも機械の理屈なんで、
どうあがいても高級アセンブラだと割り切って泥臭いポインタの側から学ぶのがいいと私は思うよ。
その泥臭いところを頑張って隠してるのが C++ ってもんなんで、
泥臭いところを知ったら C++ の色んな機能が「あー、こういうの欲しかったわー」ってなってありがたみを感じる。 ストラウストラップが言うにはC++は
低レイヤーにアクセスできる機能とオーバーヘッドが無く使いやすいように隠蔽できる機能を持っている言語というようなことを言っていて
低レイヤーの部分を知らなくていいとは言っていない アセンブラの代替言語なのだから当たり前だ。用途もOSやドライバ、マイコン向けばかりだ。
COBOL、FortranやPerl、C#やJavaの代わりに使う人などいない。
低層を隠蔽する機能などお呼びではない。 いやCOBOLの代わりには使うぞ
Fortranの代わりつーとCな客はいたねえ http://opencv.jp/cookbook/opencv_img.html#image-resize
ここのソースコードをコピペしてコンパイルしようとしたのですが
関数 `cv::Mat::release()' 内:
test.cpp:(.text._ZN2cv3Mat7releaseEv[_ZN2cv3Mat7releaseEv]+0x47): `cv::Mat::deallocate()' に対する定義されていない参照です
collect2: error: ld returned 1 exit status
このようなエラー文が出てしまいます
使っているOSはdebian stretchです
/usr/include/opencv2には必要なファイルはありました
どのようにコンパイルすればいいのでしょうか >>501
すみませんでした
こっちで質問してみます c++に限った話じゃないんだけど参考書
とかだとメソッドの後にフィールドが
書かれてる事が多いようだけど、それが
一般的なの? ちがう
一般的にはフィールドたるメンバ変数の方が先に来る
学習の都合で、メンバ変数を先に説明した方が、どう考えてもラク
メンバ関数を先に説明すると、入門書を読むレベルの初心者は間違いなく混乱するので、そんな参考書はまず見かけない
そもそもメソッドの中で使う変数は始めに宣言しておかないと使えない
結論としてはあなたが用語の取り違えをしてる……としか レイアウト、というとデータの並び順の意味にとられかねず語弊がある public、protected、privateの順に書いていくと
自然と変数はpublic関数の次に来るわ 普通アクセス修飾子の順じゃなくてフィールド→メソッドの順じゃないの
カプセル化するから変数なんてほとんどprivateだろうし
変数は変数でまとめて書いてもらわないと混乱する ユーザーにとって重要な項目から順に書く
つまり、public→protected→privateで
ユーザーに見せる必要のないprivateは一番下で 変数の宣言と関数の宣言の順序がどうでも良いのは自明
メンバ関数の定義がメンバ関数内で使用するメンバ変数の宣言に先行する場合も実験する限り合法
(規格に具体的にどういう文言で規定してあるのかは知らん
まあ定義時点で不完全な型やら値やらはテンプレートの定義で頻出するから
あんま定義と宣言の順序にこだわらない処理系の作りなのだと納得しておく
しかしなぜかテンプレートの引数でない型の定義(または宣言)と使用には厳格な順序を求められる…
次のコードはビルドが通らない
class Baz {
// struct Bar; // 左のコメントアウトを外したら逝ける
void foo(Bar& b);
struct Bar { int x, y; }
};
多分Cとの互換性のために仕様がワケワカメになった例 ルールが存在してwell documentedで、ガバナンスがきいていることが重要
お前らのオレオレ哲学なんかどうでもいい ああそっか、プロトタイプ宣言しなきゃいけないんだっけC++は
C#の脳で考えてたわ >変数の宣言と関数の宣言の順序がどうでも良いのは自明
自明かねぇ
C++11は問題になる例が思いつかないがC++98,03,14はどうでも良くない コンストラクタ実行時のメンバ変数の初期化の実行順が、初期化子の記述順ではなくクラス定義での並び順に従うっていうのがあった気がするけど、新しい規格では変わったんだっけ? >>516
うそーん、初期化子の記述順>クラス定義の並び順だと思ってた。
てか、宣言の並び順は無関係?
そら、警察官も道行く江添さんに聞きたくもなるわw >>516
微妙な表現以外、特に変わったという話は聞いたことがない
C++03 12.6.2/5
Then, nonstatic data members shall be initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).
C++20 draft 15.6.2/(13.3)
Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers). >C++11は問題になる例が思いつかないがC++98,03,14はどうでも良くない
とか書いてるから何か制約が無くなるような変更があったのかと思って聞いたんでない? ちな漏れがどうでもよい(どんな順序でも問題ない)と言ったのは
変数の宣言と関数の宣言の順序(どちらを先にするか)だからな
これ豆な C++11でもこれがあったか
struct A {
int m;
decltype(m) /*←mは先に宣言が必要*/ f() { return m; /*←mは後でもいい*/ }
};
C++11で緩和されたのは11章のどっか(忘れた) static メンバ関数と friend 関数の使い分けについて教えてください
どちらも似た機能だと思ってしまうのですが‥ あ〜、そんなこと考えたことなかったけど、クラス (メンバ関数) 内部から見たら近いっちゃ近いのかも?
クラスを定義する側じゃなくてそのクラスを使う側の気持ちで考えて。 friend 関数は public で,static メンバ関数は private で,て感じでこの前は書きました
普通はどうするものかをお聞きしたいところです すまんけど自明すぎてどう使い分けるとか説明できない。
使い分け以前にそもそも理解できているか怪しいと思う。 何度も宣伝するようで気が引けますが,前に書いたのは >>158
演算子のオーバーロードに絡むものは基本 friend で,内輪で使うものは private の static メンバ関数で,
くらいの線引きをしています.
書いてみてわかったのは「自明」という感じはしないこと,かな,考えてみれば friend 関数って他の言語にはなさそうです 何で? operatorはグローバルに出さなくても多重定義候補に挙がるぞ
俺は別の理由でoperatorをグローバルにする傾向があるが >>527
http://codepad.org/8Z3c2obA
ほー,これは不思議だなあ‥
friend をはずすとコンパイルできない
friend をつけてしまうと public に置こうが private に置こうが関係ない,という認識であっていますか? 何が不思議?
friendを外すとメンバoperator+に過剰な仮引数となりエラー
friendは「メンバではない」のでアクセス指定は無関係
1点だけ気になるのが、friendは当該クラス自体と同じスコープに新しい識別子を導入しないはず・・・
識別子はoperator+で、これのみは某か標準のヘッダで既に宣言されているということか? >>529
>operator+に過剰な仮引数となりエラー
つまり operator+ の >>528 とは違うもう一つの呼び出し書式にしないといけないわけですね.
でもこの場合は private に置くとコンパイルできない
http://codepad.org/RLo9fKuI
friend はアクセス制御如何にかかわらず「強引にpublic にする」ように見えますね‥わからない‥ friendなら、その人のプライベートにアクセスできる。それだけの意味。 ある人のfriendなら、その人のプライベートにアクセスできる。 >>531
>>522 をどうかよろしくお願いいたします. >>530
強引にpublic・・・で憶えやすいならそれでいいんじゃね?
ちな俺の憶え方はメンバでないものをどうやってprivateにするんだ、だ あるクラスX内部のstaticでpublicな関数fは、Xのインスタンスの存在に関係なくX::fという名前でアクセスできる。
あるクラスX内部のfriendな関数gは、X内部のプライベートなメンバーm_aにアクセスできる。 >>534
確かに friend 関数は「メンバーじゃない」ですか‥main() と同じような普通の関数なわけですね‥ friendは他のクラスのメンバかも知れない
そういうときも俺の憶え方なら動揺せずに済む メンバ関数より、メンバでもfriendでもない関数を使おう
って誰かが言ってた 欲しい機能がメンバでない関数で使えないとなれば
それはクラスの設計ミスないしはダサい設計だかんな
クラックできちまうのと違う提供すべき機能の欠落 >>530
(1) friendが無い場合
「z = x + y;」に出くわしたコンパイラは
1. インスタンスxに対しするC::operator+(y)(1引数)の呼び出し
2. グローバルな関数C operator+(C const& a, C const& b)(およびその亜種)の呼び出し
のあてはめを順次試みるがどちらの関数も宣言が存在しないからあてはまるものが無くエラーになる
(2) friendがある場合
friendがつくことでoperator+()はCのメンバ関数ではなく、グローバルな関数として宣言されたことになる
このとき「z = x + y;」に出くわしたコンパイラは、上の1、2の順で当てはめを試み、
グローバルな関数C operator+(C const& a, C const& b)の呼び出しと解釈する。
本来この関数はクラスCのprivateメンバにアクセスできないが、friendの力でそれができ、めでたくビルドできて動く。
細かい話は規格の人がフォローして☆ホスイ >(2) friendがある場合
最も近い(内側の)名前空間の関数になる(11.3/6-7)
friend関数がメンバーではないことがC++14に明記されていなかったようで、C++17ドラフトに追記された模様(N4659 12.2/2)
<おまけ>
宣言の場所がクラス内という事情により、リンカーはともかくコンパイラーから存在が見えにくい関数となる
この関数を使うには
・名前空間スコープで明示的に宣言し直す
C operator+(C const& a, C const& b);
・ADL(argument dependent lookup)でクラススコープの検索を発動させる
>>541でoperator+が呼び出せているのはADLによる つまりクラスの外で定義された関数をイメージすればいい
struct A { friend void operator+(A,A) {/**/} };
↓
struct A { friend void operator+(A,A); };
void operator+(A,A) { /**/ } // ただしADLが無いと見えない ドット拡張とかすればいいのにね
int static_value.fanction() = 0; // function専用
vid functionx.function(char*p){} // function専用
ファイル内スコープなんて今時ほとんど使わないから無視するか識別子重なったら同一と見做すかして
ついでにドット型はファイル内の前方参照も無くし宣言を省けるようにするとかさ >>541
>friendがつくことでoperator+()はCのメンバ関数ではなく、グローバルな関数として宣言された
なるほど,そんなところだろうと >>528 で考えておりました.
件のライブラリもどきでは,operatorX のみクラス外に公開できればいいので,friend 関数で公開しておりました
その他は(基本的に)(公開すらしたくなかったため)static メンバ関数でのprivate 宣言となりました.
そうしたいようにそう書けばいいのですが今一つ統一感を見えてなかったかもしれません.
>>540
すみません >>522
static関数とfriendは全然違うし似てるとこなんてない >>546
みなさんこれが典型的ななんの役にも立たない回答の好例です >>546
static 関数をpublic に置くか,friend 関数にするかの判断がよくわからないのです.
なにか指針があればうれしいのですが 呼ぶときにクラス名を書きたいか書きたくないかで判断
コンパイルした結果には大した差はない クラスの外の関数とオーバーロードさせたければfriend
https://ideone.com/Bfcfbq staticはメンバを触れない。friendは触れる。
それくらいしか違いないけどなぁ。
俺、フレンド関数はほとんど書いたことない。 違ったっけ。
staticってthisもってないんじゃなかった? https://ideone.com/qDEfdG
勘違いやったわ。ごめんなさい。
一個勉強になった。 メンバ変数をprotectedにする人ってなんなの?露出狂なの? そういう人が日本に一人二人いるかも知れないけど、気にするだけ損だよ 継承しても触れるようにするためだけど。継承自体がほとんどない。 クラス内に定義されたstatic関数は、そのクラスのオブジェクトが存在しなくても使える関数ってのが本来の意味。
動的なオブジェクト状態には依存せず、静的なクラス構造のみに依存するからstaticね。
対してfriendは、自分をさらけ出す人を指定するめのもの。
stream のから呼び出されるオペレーターを定義する時には、既に完成している stream (だけ)に対して自オペレーターをさらけ出してしまうのがいろいろな意味で最も効率的。
以上から、friend関数は、静的ポリモーフィズムを関数レベルでお手軽に実現したいときに使うと思っている。 表層的に言うと
staticはグローバル関数をクラススコープにして、かつアクセス制御も効くようにしたもの
friendは>>531の通り
ただそれだけのこと >>561
なんで素っ裸でコートきてんの?露出狂なの?って聞かれて
コート脱いだらちんこ見えるようにする為だよって答えてんのと同じだぞ
まったく…露出狂は社会に出ちゃいけない存在なんだから、もう二度とプログラミングするんじゃないぞ >>565
うまい事言うなあ
friendは「なんで俺にだけ素っ裸見せんの?露出狂なの?」と聞かれて
「だってお前友達じゃん。だからお前にだけ俺の裸見せてやんよ」と言ってるわけだしな」 あれだろ
日本語のガールフレンドと
英語のgirl friendじゃ意味が違うというアレ >>565
あんたに決められる筋合いはねー。災いあれ。 friendはクラスの役割を適当に分担しながら実装の隠蔽を図るのにはまあ妥当な仕組みだろうな 継承をほとんど使わないってどんな分野だろう
俺んとこではポートを叩くときのプロトコルが
似ているようで少しずつ違うなんての普通にあるし 複数のクラスのfriendが可能
staticは1個だけ >>567
親しき仲にも礼儀あり。
アクセサぐらい用意するよね。 ■ このスレッドは過去ログ倉庫に格納されています