トップページ⇒tech
1001コメント302KB

C++相談室 part34

■ このスレッドは過去ログ倉庫に格納されています
0001v(^・^)vNGNG
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
テンプレートライブラリ(STL含む)に関する質問は
専用の別スレにお願いッス。

過去スレ、関連スレ、関連リンクなどは >>2-20 あたり
0166デフォルトの名無しさんNGNG
>>144
CVSにはもう追加されてます。
次のリリースからつかえるでしょう。
0167デフォルトの名無しさんNGNG
>>160
> 仮想関数を「基底クラスへのポインタ」から呼び出す事ができるかどうか。
できる。というか、仕様書読め。

> また、基底クラスに仮想関数がない場合でも、継承したクラスを「基底クラスのポインタ」に代入すれば、
その用途のためには、規定クラスに純粋仮想関数(実態はないが型の定義だけしてある)を
定義しておく必要がある。

> もっと具体的(実践的)に、現在、知りたかった事は、インターフェース・クラスは、一番最初に継承されていなければいけない物なのかどうかです。
別に。
0168デフォルトの名無しさんNGNG
>>160
それも自分でコード書いてみればすぐに分かる事じゃない?
少なくとも返事を待つよりは早く結果がでるぞ。

呼び出される関数について、オーバーライドはインスタンスの型によって決まり、
オーバーロードは呼び出し時のポインタの型によって決まる。
0169デフォルトの名無しさんNGNG
>>160
> 仮想関数を「基底クラスへのポインタ」から呼び出す事ができるかどうか。

悪いけどこんな基本的なこと人に聞く人にC++は向いてないよ。
0170デフォルトの名無しさんNGNG
>>165
POSIXで確定だよ。

今調べてみたが、フリーのVC++ToolKitにも
ちゃんとstat.hヘッダーが含まれていた。
今はファイルサイズに限定した議論になっているけど、
実用から見るとタイムスタンプ・属性などの情報もいずれ必要になってくるだろうし。
ANSI標準でのファイルサイズ取得に固執する行為は、初心者呼ばわりされるだけ。
0171デフォルトの名無しさんNGNG
以下のパターンAとパターンBの違いについて教えて下さい。
パターンAとBの違いは、Baseクラスの関数にvirtual指定があるか、ないかです。

■パターンA

class Base {
virtual void Func(); // 仮想関数
}

class Deliver {
void Func();
}

■パターンB

class Base {
void Func(); // 仮想関数
}

class Deliver {
void Func();
}
0172デフォルトの名無しさんNGNG
>>171
質問に真摯に答えると、vtableが出来るからsizeofの値が違う。
できれば質問の意図を教えて欲しい。
0173デフォルトの名無しさんNGNG
>>171
違いって見たまんまだろ
パターンBのBase::Func()は仮想関数じゃないだけ

もしかしてDeliverはBaseから派生させたかったのか?

>>172
171に対してそれは無理な相談だ
0174デフォルトの名無しさんNGNG
>>173
確かに。ワロタ。
0175デフォルトの名無しさんNGNG
真剣にレス付けようと思っていたが、
先にリロードして正解だった。
>173がシンプルに説明をしてくれている。
後はBase::Funk()が仮想関数でないということは、どういうことかを
考えればよい。
つまり仮想関数であることにより期待される動作(これは勉強するべし)
を数え上げれば、それがすなわち2つのパターンの違いである。
0176デフォルトの名無しさんNGNG
好意的に解釈すると、
Base* a = new Deliver;
a->Func();
したときにBaseとDeliverどっちのFunc()が呼ばれるかを書いて欲しいんだろうな。
0177>>171NGNG
>>176
あ、そういうことです。

と、いうことは、

パターンAの場合は、基底クラスが呼ばれて、
Bの場合は、派生クラスが呼ばれるということでいいんでしょうか?
0178デフォルトの名無しさんNGNG
なんで自分で試してから発言しないのかを教えてくれないか?
0179デフォルトの名無しさんNGNG
>177
だから仮想関数とは何かを勉強しなよ。
>176が好意的に書いてくれた丁寧なレスの内容なんて、
本読むなりサイトの記述をチェックすればすぐにわかること。
調べたけどわからなかったからここで聞いているんですなんて
いうのは却下だよ。それは自分の無能さを公に宣言するような
ものだからな。
0180デフォルトの名無しさんNGNG
あるメンバ関数からしか呼ばない関数も
そのクラスのprivateメソッドとするべきかどうかで迷ってます。

クラス宣言が見づらくなるという、つまらない理由で
単なるstatic関数としてのみ扱うのは横暴でしょうか
0181デフォルトの名無しさんNGNG
>>180
意味がわかりません。
もっと詳しく、読んで理解できる日本語で説明するか、コードで語ってください。
0182デフォルトの名無しさんNGNG
>>180
*.cppにstaticで書いてるってことね。
関数内で関数定義が出来ればいいんだろうけど、出来ないんだよね。
そういう場合、俺はstructのoperator()で擬似的に関数内関数にしてる。
0183デフォルトの名無しさんNGNG
>>182
> そういう場合、俺はstructのoperator()で擬似的に関数内関数にしてる。
不要なハックは感心しない。
0184180NGNG
>>182
そうです、すいません
モジュール内でstatic(=ローカル)な関数の意味でした

うーん、無理矢理、関数内関数っぽくしちゃうわけですか

元々、切り分ける意味が薄い関数なんですよね。
再帰や、ちょっとしたまとまった処理程度で。
確かに散らすよりは気分はいいかも…

早速試してみます、レスありがとうございました
0185デフォルトの名無しさんNGNG
>184
そもそもprivate関数とモジュール内staticな関数の違いとして、
メンバにアクセスできる、できない、があるんだが。
0186デフォルトの名無しさんNGNG
>>183
STLと同じ流儀なんだから標準的技法なんじゃないかと
0187デフォルトの名無しさんNGNG
>>184
謝るこたーない、static関数で合ってるよ
>>181はどこが分からなかったんだ
0188デフォルトの名無しさんNGNG
static関数がstaticメンバ関数と受け止められたんだろう。
俺も一瞬そう解釈した。
0189デフォルトの名無しさんNGNG
わざわざstaticにしないで
namespace {} で囲っちゃえば?
0190デフォルトの名無しさんNGNG
namespaceで囲うと、文字数が増えるので出来れば別の方法教えてください。
0191デフォルトの名無しさんNGNG
>>182
オナニー以外の何物でもない。

>>180
横暴というかアホ。
0192デフォルトの名無しさんNGNG
>>186
何のためにoperator()が使われているか理解してないんだね。
関数内関数(←全然違うw)を模倣するためじゃないことくらい分からないと。
0193デフォルトの名無しさんNGNG
181大暴れだな
0194デフォルトの名無しさんNGNG
>>182は別にハックでもなんでもない常套手段だと思うけど
0195デフォルトの名無しさんNGNG
>>190
ん?無名namespace使えばいいだろ。
0196デフォルトの名無しさんNGNG
なぜこの状況でnamespaceが出てくるのか誰か解説してください。
0197デフォルトの名無しさんNGNG
staticの意味が・・・
0198デフォルトの名無しさんNGNG
>>192
確か、コンテナ内部で使われるんだっけ?
フォローお願い。
0199デフォルトの名無しさんNGNG
>>196
static関数に頼らないC++的な解決法とか・・・?
0200デフォルトの名無しさんNGNG
staticでいいと思う
0201デフォルトの名無しさんNGNG
>>177
逆だ
オーバーライドとオーバーロードの区別をしろ
ポリモフィズムを理解しろ
0202デフォルトの名無しさんNGNG
んー、人それぞれだとは思うけど
無理に「C++流」にせず、「C流」で構わない部分ってのもあるとは思う。
staticもそうだけど、stdioの関数群とかキャストとか。
0203デフォルトの名無しさんNGNG
>>202
うむ。漏れもそう思う。
0204デフォルトの名無しさんNGNG
cout より printf
0205デフォルトの名無しさんNGNG
てゆーかsprintf使えなくなって
stringstream使えとか言われたら
俺絶対泣くし。
0206デフォルトの名無しさんNGNG
static キーワードでファイルローカルな宣言をするのは正式に deprecated ですよ。
stdio.hとか、strstreamとか、リテラルからchar*への変換とかと同等。
0207ぼるじょあ ◆yBEncckFOU NGNG
(・3・)エェー 僕の知らない英語使わないでYO!
deprecated
【形】 《コ》〔仕様{しよう}などが〕廃止{はいし}される可能性{かのう せい}がある、
廃止予定{はいし よてい}の、
将来{しょうらい}のサポートが保証{ほしょう}されない(ので使用{しよう}すべきでない)、
0208153NGNG
>>167
どうもありがとうございます。
>>168
ポリモフィズムの時のデストラクタのように、
試してみるだけでは気付かない事があるかも知れないと思って聞きました。
(ここで聞くより本やサイトで調べろって言われれば、そのとおりなんですけども)

皆様、ご迷惑おかけしました。
今度こそ、消えます。
0209デフォルトの名無しさんNGNG
>>208
だから「聞く」とか「本やサイトで調べる」とかじゃなくて、
その前に、自分でコード書いて実行すれば結果が分かるだろう?
っていう話をみんなしてる訳で・・・
0210デフォルトの名無しさんNGNG
>>208
>ポリモフィズムの時のデストラクタのように、
>試してみるだけでは気付かない事があるかも知れないと思って聞きました。

それこそ、試した方が簡単に、確実に、良くわかるだろ・・・
0211デフォルトの名無しさんNGNG
試してみるだけでは気付かない事があるかも知れない
0212デフォルトの名無しさんNGNG
関連して質問させてください。

static関数よりも無名namespaceを使うべき、って聞いたことがあるんですけど、
(規格書にもそう書いてあった気がする。)

(1) なんでか知ってますか?
(2) みなさんはどっち使ってますか?

とりあえずワシは、規格書をもう一回読んできます。
0213デフォルトの名無しさんNGNG
>>211
同意。

まず試すことはとても重要。
でも、試して大丈夫だからといって安心してはだめ。

質問するときは
「こういう目的のために、こういうコードを書いてみました。試したら上手く動きました。でも正しいか不安です。教えてくれ。」
って感じでよろしく。
0214デフォルトの名無しさんNGNG
>>212
1. deprecated
2. neither
0215デフォルトの名無しさんNGNG
試した姿勢が文脈から感じられない質問って教える気無くすもんだよ。
質問する側は相手からうまく情報を引き出すコツを身につけるべきだ。
相手の為ではなく自分の為にな。
0216212NGNG
>>214
1. なんで deprecated になったかを知りたいのです。宜しくお願いします。
2. それはそれでアリでしょうね。JAVAみたいだけど。
0217デフォルトの名無しさんNGNG
>>216
staticは使う場所によって意味が幾つにも分かれてしまう(のでわかりにくいと言われている)から減らすため
0218デフォルトの名無しさんNGNG
>>217
へえ。そんな理由だったんだ。
だったら、なんでクラスメンバにstaticなんてキーワードをあてたんだろう。
矛盾してるよね。
0219デフォルトの名無しさんNGNG
上でも起きてるように
staticというキーワードに複数の意味を持たせる事で
実際に混乱してるからね。

でも、絶対に「非推奨」が「不可」にはならないと思うけどね。
Cが無くならない限り。
むしろ(単語の意味はともかく)、staticメンバのするために、
既存の「static」というキーワードを利用したのが混乱の原因なんだから。

関数内staticな変数だって
C++がマルチスレッドを前提とした言語にならない限り
無くなることはないだろうし。
0220デフォルトの名無しさんNGNG
>>218
file local = static
ってのは、staticって単語の誤用だからでしょ。
infinite existence = static
に統一したんでしょ。

>>219
> 関数内staticな変数だって
> C++がマルチスレッドを前提とした言語にならない限り
> 無くなることはないだろうし。

そんなことはないです。
マルチスレッドだってstaticなlock変数は極めて有効です。
0221デフォルトの名無しさんNGNG
>>215
> 相手からうまく情報を引き出すコツ
2chで一番有効なのは、
その場の人間達を小馬鹿にするような口調で間違った主張を披露して、
知識をひけらかすことに命を賭けてる厨が「正解」を携えて突っ込んでくるのを
待つって戦法ですね :-)
0222デフォルトの名無しさんNGNG
小細工の必要は人はきのこれない悪寒。
0223デフォルトの名無しさんNGNG
いや、だから
extern宣言は関数スコープでもファイルスコープでも同じように書けるのに
infinite existence変数の記法は関数内外で違う書き方が推奨されるってのがね。

違うのはスコープ(可視性)だけで、寿命その他は同じなのに。
(初期化タイミングは違うけど、「スコープが初めて有効になった時に初期化される」という意味では同じ)
0224デフォルトの名無しさんNGNG
>>220
クラスメンバと infinite existence って違う概念のような気がするなあ。
グローバル変数だって infinite だし。だからグローバルな static関数/変数は非推奨にしたって考えればいいのかな。

マルチスレッドで使うstaticなlock変数と、auto変数じゃないstatic変数って別ものじゃないかなあ。
再入可能性の制御ってこと?
0225デフォルトの名無しさんNGNG
まあ、ここでどうこう言ったって標準化委員会の目にとまるわけでもないし
std::や#include <c...>あたりから、なんとなく
Cとの互換性(というよりCしか知らない人の移行しやすさ)を軽視する方向のような気もしてるけど
それならそれで仕方ないかなって気もするし。
0226デフォルトの名無しさんNGNG
>>223
オート変数へのstatic qualifierが「変更する」のは、
寿命でしょ。スコープは変えないよ。

qualifierの行う変更について、
static: 寿命
extern: スコープ(defaultだから基本的に意味なし)
と統一したんでしょ。

で、名前のスコープはnamespace使えと。

> 違うのはスコープ(可視性)だけで、寿命その他は同じなのに。

はとんちんかん。
グローバル変数の元から持っている性質とオート変数の
static qualifierが変えた性質が同じだからって何だって言うの?




0227デフォルトの名無しさんNGNG
>>224
> クラスメンバと infinite existence って違う概念のような気がするなあ。

infinite existence: クラスメンバの性質の一つ
オブジェクトが存在しなくても存在し続けるメンバ。

staticなオート変数が関数実行中でないときも存在するのと同じ。

後半については何言いたいのかサパリ


0228デフォルトの名無しさんNGNG
>オート変数へのstatic qualifierが「変更する」のは、
>寿命でしょ。スコープは変えないよ。

なにわけわかんないこと言ってるの?
auto変数は常にauto変数であって、決してstaticではないよ。

関数スコープのローカル変数に、autoとstaticの2種類があるだけ。
0229デフォルトの名無しさんNGNG
>>227
要するに、
「いろんなタイプの変数や関数が存在するけど、とりあえず寿命がinfiniteなものに付けるキーワードはstaticでいいや」
って標準化委員会が考えたってことだね。

変なのぉ〜とは思うけど、まぁ理解はできる。
0230デフォルトの名無しさんNGNG
今までCを使っていたんだけですが、理由があってC++を使うことになりました。

プログラムの中でソケットを扱うのですけど、Cでは直接socket()等のシステム
コールを叩きますよね。
でもC++でそれをやるとC++らしくなくなる気がします。
特にselect/pollで多重化して非ブロックにして…、なんてのをやると
「オブジェクトは何所行った?」って感じがするんですよね。

そこで聞きたいのですが、みなさんはC++でネットワーク関連のプログラム
を書くときどういう設計にしますか。sourceforge.netで調べていたら
cppsocketというソケットのクラスラッパがあったりするので
そういうのをみなさんも使用(または自作)しているのかなと想像しているのですが。

ソケット周辺だけでなく、どうもC++を書いているとどこでシステムコールの
ような低レベルインターフェースを叩くか迷うんです。理想と現実というか…。
0231デフォルトの名無しさんNGNG
C++らしい手段が提供されてなくて、Cの流儀で書く事に抵抗があるのならラッパーを書くしかないじゃないか。
0232デフォルトの名無しさんNGNG
そんなあなたに
http://www.cs.wustl.edu/~schmidt/ACE.html
http://www.boost.org/
0233デフォルトの名無しさんNGNG
ソケットがオブジェクト化されててもあんまりうれしくないぞ。
所詮通信路でしかないんだから、そこはそれで割り切って、
オブジェクトのシリアライズ経路のひとつとして考えたほうがいいと思う
0234デフォルトの名無しさんNGNG
poller
http://www.kegel.com/dkftpbench/doc/Poller.html
0235デフォルトの名無しさんNGNG
>>231-234
レスありがとうございます。
ACEってのは気になるますね。
サイトの方に文章が大量にあるので、いまから読んでみます。
本も出てるみたいですね。

一方で無理にオブジェクト化すると標準入出力と同列に扱えなかったり
するんですよね。

>>232, 234さんらはやはりその手のライブラリを使うのでしょうか?
いろいろ考えてるとソケット自体をオブジェクトにするのでは無くて、
もっと上位のクラスを作って、その中で生のソケットを扱うのが良いのかなぁ、と。
例えばHTTPServerやFTPClientのようなクラスを用意して、その中で
プロトコルとソケットを管理するような感じ。
結局Socketクラスを作っても
Socket sock;
sock.setsockopt(HOGEHOGE);
sock.bind(Foobar);
みたいなことをやり始めると結局やってることはC流とは変わらないし。
0236230NGNG
最後、文章おかしいけど勘弁(意味は伝わるでしょう)。
0237デフォルトの名無しさんNGNG
でもSocketクラスのデストラクタが有効に使えるでしょ
0238230NGNG
>>237
デストラクタでソケットを閉じるということですか?
ソケットを閉じるときって結構デリケートな処理が必要になったりしますよね。
相手の為にできるだけ早く閉じたかったりすることも。

あ、そういうことをクラス内に隠蔽すると嬉しいという話か。
非同期IOなんかも隠蔽出来るとうれしいかな。

その場合select/poll等の関数は誰が保持しますか?
>>234のような専用クラス? 
0239デフォルトの名無しさんNGNG
>>230-238
環境依存にしてスレ違い。
専用スレ逝ってください。

ネットワークプログラミング相談室 Port10
ttp://pc5.2ch.net/test/read.cgi/tech/1090385857/
0240デフォルトの名無しさんNGNG
>>239
黙れ。ここはCスレじゃないんだからそんなことにこだわるな。
0241デフォルトの名無しさんNGNG
ソケットをストリームに組み込むとだいぶ変わる。
0242デフォルトの名無しさんNGNG
>>240
いやいや、そうでもない。
特にサーバアプリの場合、完全に環境依存。
ちょっとやそっとのことで汎用的なラップをできるものじゃない。
0243242NGNG
ヒントをいうと、あまりカプセル化しすぎないこと。
メンバ変数に直接アクセス出来るようにしておく事をお奨めする。
デストラクタ機能はあくまでオマケ感覚のつもりで。
0244デフォルトの名無しさんNGNG
>>243
死んどけや
0245デフォルトの名無しさんNGNG
Javaのsocketが大失敗こいてるからなあ・・・
0246デフォルトの名無しさんNGNG
>>245
そうか?
プラットフォーム、実装が複数ある中では異例の成功だと思うけども。
0247242NGNG
>>244
なぜに死すべしや?


ついでに書くと、ソケットハンドルをいつでもAttach/Detachできるようにしないとかなりツライ。
デストラクタ処理がかえって邪魔になる事もあるからね。
0248デフォルトの名無しさんNGNG
newしろや
0249デフォルトの名無しさんNGNG
>>246
まさか。あんなのtoy programでしか使わないよ
0250デフォルトの名無しさんNGNG
>>248はC/C++の開発から永久追放。
0251マイク ◆yrBrqfF1Ew NGNG
>230
QtのSignal/Slotでいい感じじゃねえか。
0252デフォルトの名無しさんNGNG
>>247 デストラクタ処理がかえって邪魔になる事もあるからね。

なりません、まだ使われる可能性があるのにインスタンスを破棄するアホでもないかぎり。
0253242NGNG
>>252
同期型ソケットしか使ったことない厨は1回氏ね。
0254デフォルトの名無しさんNGNG
非同期ソケットでも、ソケットの寿命とオブジェクトの寿命を同一にすればいいだけの話だが
0255デフォルトの名無しさんNGNG
>メンバ変数に直接アクセス出来るようにしておく事をお奨めする。

タコ助だな
0256デフォルトの名無しさんNGNG
どうせsetsockopt()みたいなのを呼んだり環境依存のフレームワークに
生のソケットを渡したりするから、生ソケットにアクセスする手段は
必要だって。完全なカプセル化じゃなくFacadeと考えた方がいい。
0257デフォルトの名無しさんNGNG
サーバソケットからacceptして生成した新インスタンスに
setsockoptし忘れて・・・なんてことが
環境依存で起こりまくりですよもう
0258デフォルトの名無しさんNGNG
サーバプログラムを書いた事ないヤシが多いのか、このスレ?

>>255
通信プログラム初心者は黙ってた方がいいね。
0259デフォルトの名無しさんNGNG
C++の勉強を始めようと思って、こういうコードを書いたのですが
#include <iostream>

int main()
{
std::cout << "hello\n";
}
こういうエラーが出てきます。どなたか解る方がいましたら教えてください。
cstdlib(22): error C2873: 'exit' : シンボルを using 宣言の中で使用することはできません。
cstdlib(19): error C2873: 'abort' : シンボルを using 宣言の中で使用することはできません。
cstdlib(22): error C2039: 'exit' : 'operator``global namespace''' のメンバではありません。
cstdlib(19): error C2039: 'abort' : 'operator``global namespace''' のメンバではありません。
0260デフォルトの名無しさんNGNG
sockoptの挙動が環境ごとに違うことは知らない奴が多そう
あとsignalも
0261デフォルトの名無しさんNGNG
>>259
#include <cstdlib>
0262デフォルトの名無しさんNGNG
長時間かけて小出しに煽ってるところを見ると
必死でググりながら調べてるのかな?
勤勉で結構。
0263デフォルトの名無しさんNGNG
>>261 すみません、<cstdlib>をインクルードしても駄目でした。
再インストールでしょうか。。。
0264デフォルトの名無しさんNGNG
環境依存部をラップする事が不可能って断言してる香具師いるけど、wxWidgetsとか、想像も出来ない世界にすんでるんだろうな
0265デフォルトの名無しさんNGNG
>>242はアホだから放置しましょ
■ このスレッドは過去ログ倉庫に格納されています