C++相談室 part34
■ このスレッドは過去ログ倉庫に格納されています
0001v(^・^)v
NGNGただし質問の前にはFAQに一通り目を通してください。
テンプレートライブラリ(STL含む)に関する質問は
専用の別スレにお願いッス。
過去スレ、関連スレ、関連リンクなどは >>2-20 あたり
0756デフォルトの名無しさん
NGNGスレの書き方・質問の仕方から察するに、プログラマに向いてない。
それが一番の問題。巻き添えを食うであろう同僚PGが気の毒。
0757デフォルトの名無しさん
NGNGなんだと
0758デフォルトの名無しさん
NGNGこりゃまた強引なネタで C++ の話題に戻しにかかってきたねぇ・・・
もしネタじゃないなら、ネタじゃありません、とか書いておいた方が良いよ。
0759751
NGNGそうなんですか?
なにがおかしいのでしょう。
>>758
C++の話題に戻すのが目的でもありませんし、ネタでもないのですが
なにがおかしいのか教えていただけませんか?
みなさんのレスから想像すると、何か変なこと聞いてます、俺?
0760デフォルトの名無しさん
NGNGこれは関数宣言
0761デフォルトの名無しさん
NGNGこの書き方は何が問題なの?
0762デフォルトの名無しさん
NGNG0763デフォルトの名無しさん
NGNG0764デフォルトの名無しさん
NGNGoperator new
std::get_temporary_buffer
どっち使うのが主流?
0765デフォルトの名無しさん
NGNG756 じゃないけど「・・・と思った」とか「納得いかない」っていうのは、
自分でアレコレ調べてみる動機としては結構だけれども、
単に「・・・と思ったけど違った。納得がいかない」っていう質問はちょっとアレだろ、
訊かれたほうも困るだろ、ということでは?
>>751-752
ちなみにエラーの意味はだいたいこんなところ。
(1) エラー
非集合体の型 'SampleClass ()()' として定義された 'sclass()' に対して
メンバ 'action' が要求されました。
(2) エラー
非集合体の型 'UserClass()(SampleClass (*)())' として定義された
''uc(SampleClass (*)())' に対してメンバ 'doAction' が要求されました。
0766751
NGNG>>760
あ、言われてみればそうですね。
ということは>>753のいう奇妙な解析というのはこれのことだったのですね。
実引数の無い時は関数宣言と解釈されるから、そのときは特別扱いで
空の括弧はなし、と。
ということは(2)に関しても
UserClass uc(SampleClass());
SampleClass()という関数として解釈されてるということでしょうか?
しかし、次の行のuc.doAction()をコメントアウトするとコンパイル&実行
できます。ただし、SampleClass::SampleClass()は呼ばれていないようです。
こちらはどういうことなんでしょう。
>>762
(More) Effective C++なら持っているんですが、その本は持っていません。
明日大至急立ち読みしてきます。
0767デフォルトの名無しさん
NGNGUserClass uc(SampleClass());
これは 引数 void、関数値 SampleClass の関数へのポインタを引数に取る関数の宣言だ
(More) Effective C++ 持ってるのに分からないなんて終わってるなお前
0768デフォルトの名無しさん
NGNGuc っていう関数として認識されてる。この関数の型は UserClass()(SampleClass (*)())
SampleClass を返す引数無しの関数ポインタを引数とする、UserClass を返す関数。
型の記述を読めるようになった方が良いよ。
0770デフォルトの名無しさん
NGNG配置new…かな?
0771デフォルトの名無しさん
NGNG何をするためにそいつら使うの?
0772デフォルトの名無しさん
NGNG{
char a[10];
int b;
char c[5];
public:
func();
};
こんな感じのクラスがあったとします。
これのインスタンス class Test test;
を定義して、例えば char c[5]
の先頭アドレスを取得したいんですが、
良い方法はないですか?
0773デフォルトの名無しさん
NGNGclass Test
{
char a[10];
int b;
char c[5];
public:
func();
char* get_address(int i) { return c + i; }
};
Test test;
char* p = test.get_address(5);
0775デフォルトの名無しさん
NGNGC++のクラスでもoffsetofマクロがそのまま使える。調べてみるべし。
0776デフォルトの名無しさん
NGNG先頭アドレスってそういうことだったのか?読みが深いな。
0778722
NGNGにキャストされているマクロになってました。
>>772のc[5]のアドレスを指定されてそこに書き込む関数、
を考えると
static Test test;
SetAAA(const char *str)
{
Test* p;
size_t offset;
char* dest;
p = &test;
offset = offsetof(Test, c);
dest = p + offset;
strcpy(dest, str);
}
のような事をしたいのですが、この場合、安全なキャスト
はどのようになりますか?
dest = (char*)(p+offset);
と強引にやってしまってよいでしょうか?
0779デフォルトの名無しさん
NGNGC++を使うなら(char *)とやらずにreinterpret_cast<char*>(p + offset) と書くべき。
働きは変わらないが。
0780デフォルトの名無しさん
NGNGまあいいけど。
0781デフォルトの名無しさん
NGNGメンバへのポインタはアドレスじゃないから、>>778への最適解にはならんな。
実際内部クラスへの委譲をするにはメンバへのポインタではなくoffsetofマクロ
を使ってアドレスを求める必要があるしな。ケースバイケースかな。
0782デフォルトの名無しさん
NGNGoffsetofを使ってメンバのアドレスを求めるときは、
まずchar *にキャストしてそれからoffsetを加え、さらに実際のメンバの型にキャストするから
えらい汚くなるのよん。
dest = reinterpret_cast<char*>(p + offset);
じゃ正しく動かないねん。
0783デフォルトの名無しさん
NGNGi->m_p = NULL;
これを「for_each」を用いた式に変更したいんですが
出来るでしょうか?
0784デフォルトの名無しさん
NGNG0785デフォルトの名無しさん
NGNG{
char a[10];
int b;
public:
func();
char c[5];
};
Test test;
char *p = test.c;
ところでこれじゃだめなのか?
0786デフォルトの名無しさん
NGNGとかか?
0787デフォルトの名無しさん
NGNGmem_func1をパクってmem_assignを作りました。
ありがとうございました。
0788デフォルトの名無しさん
NGNGprivate:
int hage; //他メンバ変数が「20」個
public:
void func( int n ){
switch(n){
case CASE0: hage達に関する複雑な処理; break;
case CASE1: hage達に関する複雑な処理; break;
//以下延々と「30」個
}
}
};
case文が多いので、そこの処理だけを他クラスに切り分けたいと思ったのですが(Stateパターン?)、
切り分けたクラスからHogeのメンバ変数であるhage達にアクセスする良い手段は無いでしょうか。
・getter/setterを20個ずつ用意する
・friendを30行書く
・メンバ変数を全て構造体にまとめ、切り分けたクラス達に渡す
思いついたのは、どれもいまいち _| ̄|○
0789デフォルトの名無しさん
NGNG0790デフォルトの名無しさん
NGNG・必要なメンバ変数に相当するものを構造体にまとめ、切り分けたクラス達に(getter, setterで)渡す
に1票。インタフェイスが明確になるし。
0791デフォルトの名無しさん
NGNG0792デフォルトの名無しさん
NGNGスレ違い
0793デフォルトの名無しさん
NGNGレスありがとうございます。
やはりそういうやり方(俺のより遙かに洗練されてますが)しか無いのですね。
リファクタリングの本なんか見ると、switch-caseは全てstateパターンに
しろと言いかねない勢いで記されていますが、こういう風に分けなければとなると、
かえって解りづらい気がしてしまいますねぇ・・・。
0794デフォルトの名無しさん
NGNG0795デフォルトの名無しさん
NGNG「参照されないstatic変数・関数は削除される」という変更が入っているらしいので、
早速試してみたところ、たしかに削除された。
static int x = 0; // この定義に対する領域の確保は無い
ふと思い立って、無名名前空間に置き換えたところ、変数領域の確保が出力された。
namespace { int x = 0; } // この定義に対する領域が確保される
無名名前空間によるファイルローカルな変数・関数は、
staticと同様に参照されない場合に削除してはいけないのでしょうか?
0796デフォルトの名無しさん
NGNG0797795
NGNGttp://gcc.gnu.org/ml/gcc/2004-01/msg02323.html
ttp://gcc.gnu.org/ml/gcc/2004-01/msg02341.html
gcc開発者側の言い分を勝手に要約すると、
「無名名前空間がstaticのかわりに使えるようにしたかったのは分かるが、
現状の規格に従う限りそれらは意味的に違うものになってしまっている。
最適化のために規格に則ったプログラムを犠牲にするわけにはいかない。
今までどおりの"static"として扱って欲しいのなら、"static"と書け。」
という感じ。
gccの現在の実装を盾にしている感もあったのだが、
ソースを見ずしてそこを非難するわけにはいかない。
ついでに、標準委員会の関連する動きも貼っとく。
ttp://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#223
ttp://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#167
ttp://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#174
cwg_active.html#223 ってのが最悪で、
「deprecatedだからどうなの?」っていう話が未だに決まってないらしい。
激しく萎えた。
0798デフォルトの名無しさん
NGNG0799デフォルトの名無しさん
NGNGきれいに消えるんだろうか?
0800デフォルトの名無しさん
NGNG消えたからって特になんの効果もなさそうな気が。
0801デフォルトの名無しさん
NGNG処理系によっては、いくつか main() 走る前にコンストラクタが動いて、
動的メモリ割当を行うオブジェクトがあったりする。メモリ管理に手を
入れる場合に、ひじょーに面倒臭い。
0802デフォルトの名無しさん
NGNGそんなオブジェクトも削除されるのか?
0803デフォルトの名無しさん
NGNG「A」というクラスに「B()」というメソッドがあった場合の、
Bのポインタ変数の宣言を教えて下さいでつ。
0804デフォルトの名無しさん
NGNG0805デフォルトの名無しさん
NGNGvoid B(); なら void (*A::f)();
0806デフォルトの名無しさん
NGNGあ、*の位置間違えた、と思ったら >>804 が書いてた。
0807デフォルトの名無しさん
NGNG例えばhoge.cppとhoge.hが共に、stdhoge.hを必要とする場合
hoge.hの先頭に#include<stdhoge.h>する方法と
hoge.cppの先頭に、stdhoge.h>hoge.hの順で#includeする方法がありますが・・・。
後者は他でhoge.hを使う場合にも同順でやらなければと不便で、今まで避けていましたが、
世のライブラリを見ると、特定の順序でincludeせよという物も多く、疑問に思った次第です。
0808デフォルトの名無しさん
NGNGおかしなことになるだろうし、してあればコードの解釈は1回ですむ
からそこまで効率が落ちるってことはないだろうし。
0809デフォルトの名無しさん
NGNGファイルは単独で意味を持つ方が望ましいという観点から見ても、前者がいい。
>世のライブラリを見ると、特定の順序でincludeせよという物も多く、疑問に思った次第です。
標準ライブラリがそうでないように、そういう注文を付けるライブラリは怠慢だと思う。
0810デフォルトの名無しさん
NGNG0811デフォルトの名無しさん
NGNGC++スレでそんな事を嘆くべきかな?
テンプレートが記述されたヘッダをインクルードする時に、
避けられないことだと思うけどなぁ。
0812デフォルトの名無しさん
NGNG0813デフォルトの名無しさん
NGNGC++のstatic宣言されていないメンバ関数を渡して、
実行させることはできますか?
staticでないC++のメンバ関数の実行には、仮想関数など
ランタイム時に決定される種類のものがある。だから、
Cライブラリ関数がそれを関知して動作することは不可能
→ゆえにstaticしか通らない。
と考えているのですが。
0814807
NGNGとりあえず唯一解みたいのが無くて安心しました。。
>>808
私の使っている駄目なIDEだと、cppの方にincludeしてないと
入力補助が働かないので、実利の面からその考えは納得できます。
>>809さんのレスが、最も同感です。
ちなみに私が悩んだライブラリの筆頭がWTLです。
>>810-811
それもまた、もっともですよね…。かなり嫌ではあります…が。
0815デフォルトの名無しさん
NGNG概ねその通り。
まあ、渡せない理由は
仕様的には、型が違う
実装的には、暗黙のthisが引数に含まれる
からだけどな。
0816デフォルトの名無しさん
NGNG仮想関数などを使っていなくても、C 風の関数ポインタは
"this"が何であるのかっていう情報を持っていないので、
C風の関数ポインタを用いてメンバ関数を呼び出すことは出来ません。
0817デフォルトの名無しさん
NGNGプログラミング言語C++ 第3版 15.5
> メンバポインタは、変数ポインタや関数ポインタとは異なり、
> メモリの位置を指すポインタではない。
> メンバポインタは、ポインタというよりも構造体オフセット、
> 配列の添え字に近い。
0818813
NGNG最初、スレッドの初期化等を抽象化する基底クラスを
用意し、派生クラスではrun()メンバ関数のみを実装
すれば、コンストラクタ内部で自動的に
pthread_create(..., run, ...);
が呼ばれてスレッドが生成される...みたいな
スレッドライブラリを考えていたのですが....
スレッド生成はWin32ならbeginthreadex_だし、
Linuxならpthread_createだしで、けっこう相違が
あるので、隠蔽したいんですよ...。
どういう設計にするのが妥当でしょうか?
いままでCだけで書いて来たので、実際に応用しようと
するといろいろわからないことが...
0819デフォルトの名無しさん
NGNGスレッドで実行される関数に少なくともポインタが格納できるサイズのパラメータが渡せるはずだから、
そこに this を reinterpret_cast して渡してあげて、スレッドの開始関数 (static) では単に
static int ThreadProc(..., void* arg)
{
return reinterpret_cast<ThisClass>(arg)->run();
}
0820デフォルトの名無しさん
NGNGreturn reinterpret_cast<ThisClass *>(arg)->run();
0821デフォルトの名無しさん
NGNGどうでもいいけど、スレッドのクラスによるカプセル化は止めた方がいいよ。
ま、C中心だったのであれば、潔癖なカプセル化はしないだろうけど、念のため。
0822デフォルトの名無しさん
NGNG> スレッド生成はWin32ならbeginthreadex_だし、
> Linuxならpthread_createだしで、けっこう相違が
> あるので、隠蔽したいんですよ...。
差異の吸収はboostにやらせるのはどうでしょ?
0823デフォルトの名無しさん
NGNGそうなの?漏れけっこうガチガチにカプセル化しちゃたけど
特に不便を感じた事はなかったな。。。
>818みたいに,いろんな場所で動かす事を考えると
大変になるって事?
それとも漏れのカプセル化がまだユルユルだったのかな。
0824813
NGNGすみません。
reinterpret_castを使ったスレッド生成関数の
startup_routineを作っても、pthread_createや
親クラスへもっていく方法がわかりません。
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
class Thread {
public:
virtual int run(void *) = 0;
protected:
pthread_t t_;
};
class TSub : public Thread {
public:
TSub();
int run(void *);
protected:
};
static void * stub_thread(void *pParam)
{
reinterpret_cast<Thread *>(pParam)->run(pParam);
return NULL;
}
(つづきます)
0825813
NGNG{
pthread_create(&t_, NULL, stub_thread, (void *)this);
}
int TSub::run(void *pParam)
{
sleep(3);
return 0;
}
我ながら....情けなくなるのですが、TSubのコンストラクタに
書いてある内容をThreadのコンストラクタかメンバ関数に
もっていきたいわけです。
0826813
NGNGスレッドAPIを#defineで再定義していました。返り値なども。
ただ、スレッドプログラミングを進めるにつれ、
スレッドが使うヒープなどを終了時に自動的に回収したいとか、
pthreadそのままなのでprimitive過ぎて使いにくいとか、
いろいろ不満がでてきたのです。
Boost、恥ずかしながら今初めて聞きました。
ドキュメントを読んでみようと思います。
0827デフォルトの名無しさん
NGNGclass Thread {
public:
int Start()
{
return pthread_create(&t_, NULL, stub_thread, reinterpret_cast<void *>(this));
}
int Join(void** value_ptr = 0)
{
return pthread_join(t_, value_ptr);
}
protected:
static void * thread_func(void *pParam)
{
Thread *pThis = reinterpret_cast<Thread *>(pParam);
return pThis->run(pParam);
}
virtual int run(void *) = 0;
protected:
pthread_t t_;
};
class TSub : public Thread {
public:
TSub();
protected:
int run(void *) { sleep(3); return 0; }
};
0828デフォルトの名無しさん
NGNGreturn pthread_create(&t_, NULL, stub_thread, reinterpret_cast<void *>(this));
の stub_thread は thread_func の間違い。
ただ、今から書くのならば
class IRunnable {
public:
int run() = 0;
};
みたいなのを単独でインタフェイスとして定義して、Thread クラス本体と run を実装する
クラスを分ける方がよいと思う (Thread::Start の引数として IRunnable* を取る)。
0829813
NGNGキタ━━━━(゜∀゜)━━━━!!
最初思っていたことは上記のコードでできそうです。
ありがとうございました。
で。IRunnableの話なのですが、Thread I/Fとして
のclass Threadから、run()を追い出すとどのような
メリットがありますか?
まずThreadクラスのインスタンスを生成/管理する
ThreadFactoryとかThreadPoolとか作っておいて...
それらとは別に作っていたクラス
(例えばScreenManagerとか)で、値の監視的要素が
出てきたら、おもむろにIRunnableをくっつけて
run()だけ実装して、
ThreadFactoryに「スレッドにdispatchしてくれ」と
頼む、みたいな感じでしょうか。Start()が参加で、
Join()が脱退みたいな。
0830デフォルトの名無しさん
NGNG0831デフォルトの名無しさん
NGNG0832デフォルトの名無しさん
NGNGSocketとかコンソールとか、どのOSでも似たような機能を備えていそうなものだけカプセル化するべきだ。
0833デフォルトの名無しさん
NGNGグローバル変数はアプリケーションインスタンスの
インスタンス変数って考え方でいいじゃん。
あとアクセス制御をどうするかって論点に絞るだけ。
0834デフォルトの名無しさん
NGNGここはC++でどうやるのがいいか悪いかを論じる。
0835デフォルトの名無しさん
NGNGポータビリティを重要視したライブラリを真っ向から否定ですか?
0836デフォルトの名無しさん
NGNGプラットホーム間のポータビリティとは限らんでしょ。
スレッドやソケットはさすがに微妙だと思うよ。
もろシステムコールじゃん。明らかに他のジャンルと異質。
0837デフォルトの名無しさん
NGNGポータビリティはOSの特色を生かせない低賃金がする言い訳
個々のOSの特徴や性能を100%引き出してこそプロ
0838プッ
NGNGポータビリティのある言語だからプロ向けじゃ(ry
0839デフォルトの名無しさん
NGNG0840デフォルトの名無しさん
NGNG決して「切り込み隊長」的な仕事をしない
0841デフォルトの名無しさん
NGNG0842デフォルトの名無しさん
NGNG移植性を追及すべきか、アーキテクチャへの最適化をついきゅうすべきかを合理的に判断してこそプロ
0843デフォルトの名無しさん
NGNG0844デフォルトの名無しさん
NGNG両立してこそプロ(の技量)
0845デフォルトの名無しさん
NGNG0846デフォルトの名無しさん
NGNG0847デフォルトの名無しさん
NGNG無能ですね
0848デフォルトの名無しさん
NGNG0849デフォルトの名無しさん
NGNGお前が出来ないからって、他の人も出来ないと思うな
0850デフォルトの名無しさん
NGNG0851デフォルトの名無しさん
NGNG0852デフォルトの名無しさん
NGNG0853デフォルトの名無しさん
NGNG0854デフォルトの名無しさん
NGNGその逆のメソッドはありませんか?
MFC CStringのMakeUpper()やMakeLower()みたいな感じの。
0855デフォルトの名無しさん
NGNG■ このスレッドは過去ログ倉庫に格納されています