C++相談室 part34
レス数が900を超えています。1000を超えると表示できなくなるよ。
0001v(^・^)v
NGNGただし質問の前にはFAQに一通り目を通してください。
テンプレートライブラリ(STL含む)に関する質問は
専用の別スレにお願いッス。
過去スレ、関連スレ、関連リンクなどは >>2-20 あたり
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デフォルトの名無しさん
NGNG0856デフォルトの名無しさん
NGNGlocale対応バージョンがうまく書けない。
0857デフォルトの名無しさん
NGNG0858デフォルトの名無しさん
NGNG派生クラス作っときゃええやん
使えるクラスができたら売るとか・・・
0859デフォルトの名無しさん
NGNGそりゃ、localeのせいだろ。
0860デフォルトの名無しさん
NGNG純粋仮想関数の中身を実装しないとコンパイル時に関数がないと言われるのですがなんででしょう?
↓ソースはこんな感じです。
#include <time.h>
#include <iostream>
class DyingMessage{
virtual void say1() = 0;
virtual void say2() = 0;
protected:
~DyingMessage(){
( time(NULL) %2 ) ? say1() : say2();
}
};
class JiipanKeiji : public DyingMessage {
void say1(){ std::cout << "なんじゃこりゃー"; }
void say2(){ std::cout << "おらぁ死にたくないよ、死にたくない、死にたくないよ・"; }
};
class RAOU : public DyingMessage {
void say1(){ std::cout << "我が生が(略"; }
void say2(){ std::cout << "我が生涯に一片の悔いなし!ウオァァァアア!"; }
};
int main(void){
JiipanKeiji jk;
RAOU r;
}
0861デフォルトの名無しさん
NGNG~DyingMessage() が実行されるときには、ジーパンもラオウも既に死んでいる。
0862デフォルトの名無しさん
NGNGコンストラクタとデストラクタ内では、仮想関数が仮想になれない。
デストラクタを仮想にしてそこに書くしか。
0863デフォルトの名無しさん
NGNG内容的に古いらしいのですが、大丈夫なのでしょうか?
0864デフォルトの名無しさん
NGNGまじで
台詞はいてからじゃないと名シーンが台無しに・・・。
>>862
すみません、virtual抜けてましたね。
でもデストラクタにvirtualつけてもやはりコンパイル通らないっす
って仰っているのはデストラクタにvirtualつけろってことではない?
それで実験としてDyingMessageのsay1とsay2を
cout << "犯人はヤス"; と定義してみたらと、
ジーパンもラオウも「犯人はヤス」しか言わなくなりました。
な、なにゆえ?
0865デフォルトの名無しさん
NGNG処理の順番はこうなる。
DyingMessage()→RAOU()→ラオウの生涯→~RAOU()→~DyingMessage()
~RAOU()のタイミングでラオウは天に還ってしまう。
0866デフォルトの名無しさん
NGNG関数呼び出しは(virtualであっても)「そのクラス」として行われるよ。
DyingMessageクラスではsay1, say2の中身は存在しないから、
コンパイラのメッセージは正しい。
実行時にヌルポ(pure virtual function call)を出す実装もある。
細かい話をすると、デストラクタやコンストラクタが親クラス→子クラス
と渡るときに、vtblのポインタが書き換わる。
これ、Javaと逆だから、多言語を渡り歩く人は要注意ッス。
Java方式もまたそれで問題あるんだけどね・・・
0867860
NGNG中身(インスタンス)はRAOUだから、say1、2はラオウのものを呼んでくれてもいいのに( ´Д⊂ヽ
>>866
>細かい話をすると、デストラクタやコンストラクタが親クラス→子クラス
>と渡るときに、vtblのポインタが書き換わる。
まじですか。vtblのポインタが書き換わるんですか。
main関数内と ~DyingMessageでのジーパン、ラオウのインスタンスのメモリアドレスが一緒だったんで、
ジーパンとラオウのvtblのsay1、say2が呼び出されてうまくいくかと思ってたのですが納得です。
結局のところ、どうしよう。
~DyingMessage上でラオウのsay1が実行させたいのですが。なんか考えます。
ありがとうございました。
0868デフォルトの名無しさん
NGNG> ~DyingMessage上でラオウのsay1が実行させたい
そうはいってもそのときにはもうラオウは居ないから、
ラオウに追加したメンバは触れないぞ。
生きているうちに遺言を作っておいて DyingMessage に保持させるといいかもしれない。
0869デフォルトの名無しさん
NGNG~DyingMessageが実行される時には
「お前(ラオウ)はもう死んでいる」から
ラオウのメンバを無理矢理呼び出すのもダメだよ。
0870860
NGNGできれば、>>860のラオウやジーパンクラスのソースのようにsay1、say2のみを定義するだけで他は何も手を加えず、
後は親クラスのDyingMessageがsay1、say2を使って処理してくれるようなのが理想なんです。
できるだけ子クラスは記述しなければならないソースを減らしたいんです。
でも、確かにラオウは破棄されてしまうわけだから今回の場合は無理っぽいですね。
>生きているうちに遺言を作っておいて DyingMessage に保持させるといいかもしれない。
それはいいアイデアかもしれないっす。ありがとうございます。
0871デフォルトの名無しさん
NGNG0872デフォルトの名無しさん
NGNGstd::stringの派生クラスを作る奴は糞。
0873デフォルトの名無しさん
NGNG{
public: ~x() { std::cout << "x::dtor" << std::endl; }
};
main()
{
std::string* p=new x();
delete p;
}
実行結果
x::dtor
問題なし。
0874デフォルトの名無しさん
NGNG環境は?
0875デフォルトの名無しさん
NGNGお前が気にするのはそこなのか?
この場合問題なのはデフォルトコンストラクタしか使えんことだろ。
0876デフォルトの名無しさん
NGNG実行結果
0877デフォルトの名無しさん
NGNGOh! Me としたことが釣られてしまいましたNeー!
0878デフォルトの名無しさん
NGNG0879デフォルトの名無しさん
NGNG0880デフォルトの名無しさん
NGNG> std::stringの派生クラスを作る奴は糞。
まぁ、作るなとは言わんが、この場合は
tolower(std::string&);
toupper(std::string&);
っつーフリー関数にしておいた方が、何かと幸せになれる気がする。
0881デフォルトの名無しさん
NGNG0882デフォルトの名無しさん
NGNGstd::ifstream fin("somefile");
char str[1];
fin.getline( str, 256 ); // この結果勝手に256に拡張されるっぽい
などとできてしまうのですけどこれって仕様ですか?
0883デフォルトの名無しさん
NGNG未定義動作です。
0884デフォルトの名無しさん
NGNG拡張をしないまま暴力的に 256 byte 書き込んできてしまうだけ
道路の拡幅工事を立ち退き交渉も予告もせずにおっぱじめるようなもの
何が起きるのかは、おそらくご想像のとおり・・・
0885882
NGNG今度から気をつけます。ありがとうございました。
0886デフォルトの名無しさん
NGNGuppercase_traits作るんでもいーけどさ、
stringとの混用を前提とする場合、他にどーしよーもねーだろ
0887デフォルトの名無しさん
NGNG0888デフォルトの名無しさん
NGNGそのuppercase_traitsって、何してくれるの?
0889デフォルトの名無しさん
NGNG>>880
でいいやん。
なんで継承したがる?
つうか良く考えろよ。今から分かりやすく説明するからな。
お前は機能XXXを追加したくなった。
機能追加は継承だという浅はかな考えからstringから派生することにした。
class MyString : public std::string{
public:
void XXX();
/* 他のメソッドは略 */
};
こうしちゃったらさぁ、機能XXXを使うには
必ずMyStringクラスを構築する必要が出来るよな
MyString mystr=std_string_variable;
mystr.XXX();
これってかなーりムダだよな。
0890デフォルトの名無しさん
NGNGちっとも解りやすくないぞ。何が言いたいんだ?
アップキャスト後に追加メソッドを使うコンテキストでへ来ちまったら
ダウンキャストが必要になるのはどんな作りのクラスでも一緒やん。
継承を全面否定したいのなら、同意はしないが理解はできる。
0891デフォルトの名無しさん
NGNG馬鹿はスルーしろよ
0892デフォルトの名無しさん
NGNGvirtual じゃないんじゃね?
>>889はJava厨の釣りと見た。
0893デフォルトの名無しさん
NGNG0894デフォルトの名無しさん
NGNG0895デフォルトの名無しさん
NGNG↑
メソッド追加するだけなのにpublic継承してる所が釣り
0896デフォルトの名無しさん
NGNG機能追加つーたら継承そのものやんけ
なんで「異常」な手段に拘るんだよ
0897デフォルトの名無しさん
NGNG0898デフォルトの名無しさん
NGNG0899デフォルトの名無しさん
NGNG0900900ズサーーー!!!
NGNG∩___∩ |
| ノ\ ヽ |
/ ●゛ ● | |
| ∪ ( _●_) ミ j
彡、 |∪| | >>899
/ ∩ノ ⊃ ヽ
( \ / _ノ | |
.\ “ /__| |
\ /___ /
0901デフォルトの名無しさん
NGNG0902デフォルトの名無しさん
NGNG0903889
NGNGよし、じゃあXXXとか言わずにuppercaseで書いたるか。
struct MyString : public std::string{
void uppercase();
};
ほれ、出来た。これでMyStringの大文字化はラクショーさ。
ああだけど、std::stringを使ってる部分もあるんだった。
これも大文字化しないといけない。
継承で機能追加
MyString mystr=std_string_variable;
mystr.uppercase();
std_string_variable=mystr;
外部関数で機能追加
uppercase(std_string_variable);
これでどうやろう?
基本的に継承は仮想関数のオーバーライドのためか
protectedなメンバに触りたい時くらいにしか使うべきではない。
0904デフォルトの名無しさん
NGNG>MyString mystr=std_string_variable;
おまえ追加機能つかうちゅーてる時に予めアップキャストしとくんかい
アフォ言いな、比べ方の条件がちゃうやないけ!
0905デフォルトの名無しさん
NGNGJava厨っぽいな
継承悪
コンポジットサイコーみたいな
思考停止したデザパタ厨
0906889
NGNG?
じゃあstd_string_variableを大文字化するにはあんたならどうするん?
てかさっきから気になってたんやけど、アップキャストなんてしとらへんよ
アップやないし、そもそもキャストでもない
>>905
オレのことじゃないよな。俺は外部関数使えいうとるし
0907889
NGNGstd::stringを継承して、そのサブクラスにメンバ関数追加するのが一番だと思ってるんか?
0908デフォルトの名無しさん
NGNGああ、確かにstd_string_variableの定義を隠したままだねw
レス数が900を超えています。1000を超えると表示できなくなるよ。