C++相談室 part28
■ このスレッドは過去ログ倉庫に格納されています
0001v(^・^)v
NGNGただし質問の前にはFAQに一通り目を通してください。
また、テンプレートライブラリ(STL含む)に関する質問は
専用の別スレへどうぞ。
過去スレ、関連スレ、関連リンクなどはこちら>>2-13
0159デフォルトの名無しさん
NGNGありますが、実際にやってみると非常に面倒くさいと感じます。皆さんは
そのへんどう解決してますか?気にせずがんがん再コンパイルですか?
それとも、ちゃんと設計してからコード書けやごるぁ!!!って感じですか?
0160デフォルトの名無しさん
NGNGクラスやコンポーネントの依存関係を気にするべき。
コンパイル時間なんて気にスンナ。
あ、gccをご利用?そりゃごめんなさい。
0161デフォルトの名無しさん
NGNG0162デフォルトの名無しさん
NGNG気にしたくないよ
気にしたくないんだよおおお
んなこと言ったって・・・(泣
0164デフォルトの名無しさん
NGNGコピペで再利用するわけじゃないし。
0165デフォルトの名無しさん
NGNG0166デフォルトの名無しさん
NGNG>147の織り交ぜるってのは
A & A::ap=A::a();
何故こうしない?と言うことでは。
しかし、普通に、一番最初のstatic A & a();呼び出しで初期化すればええやん、と思うのだが。
pimplは、めんどくさくは無いけど、
小さいオブジェクトにnewは何となく嫌症候群だからなぁ。
0167デフォルトの名無しさん
NGNGMACアドレスを取るのはどういう方法があるのでしょうか?
IPのMACで例えばWindowsなどの処理系です
ipconfig.exeを使う方法があるのですがバージョンなどの問題などありますから
0168デフォルトの名無しさん
NGNGIPにはMACアドレスという概念はありません。
Windowsは処理系ではありません。
0169デフォルトの名無しさん
NGNG物事を正しく把握し、説明する練習をしてからまたもどってこい。
0170デフォルトの名無しさん
NGNGヒープの分断化を招きますか?
やはりループ外で事前に定義しておくか、自前でアロケータを書くべきでしょうか?
ちなみにalloca()などを使ってスタック上にアロケートするアロケータを書くことは
この場合妥当な選択でしょうか?
0171デフォルトの名無しさん
NGNG話はどこにいったの?
0172デフォルトの名無しさん
NGNG0173デフォルトの名無しさん
NGNG#include <ctime>
using namespace std;
int main()
{
std::time_t systime = std::time(0);
std::tm *cur = std::localtime(&systime);
cout << systime;
}
上のようなプログラムを実行すると1078750166と表示されるのですが、
これを2004/3/XX XX:XX というようにするにはどうすれば?
0174デフォルトの名無しさん
NGNGてかC++じゃなくてCの話題だねそれ
0175デフォルトの名無しさん
NGNG0176デフォルトの名無しさん
NGNG本当にそのフォーマットじゃなきゃいけないのならstrftime
あとはリファレンス見てくれ
0177173
NGNGお答えサンクス。
てぇことはですよ、プログラム中で時刻を使いたい場合は
その文字列から時分秒を求める必要があるンすか?
0178こんぴゅー
NGNG2) a=3;
3) d; 注:この直前の文はchar d[10];
4) ((a=3)>2 || (b=0)<-1);
5) "abcdefg";
6) printf("%s",string="abcdef"); 注:変数stringは文字型へのポインタ変数
各式の評価値を教えてください(理由もお願いします)
0179デフォルトの名無しさん
NGNGお前が使っているstd::localtimeはいったいなんなのかと(ry
0180173
NGNGじゃあ、どうすれば良いですか?
0181デフォルトの名無しさん
NGNGだから>>175->>176の関数を今すぐ調べろ。
0182デフォルトの名無しさん
NGNGCの標準関数は別の名前空間にしておくべきではなかったか。
0183デフォルトの名無しさん
NGNGlocaltime の引数は何なのか調べればよろしいかと。
0184ルージン
NGNGtemplateスレで聞こうと思ったのですが下がっているので
ここに来ますた。
class CTest
{
public:
void f() const
{
g();
}
void g(){}
};
このコードはもちろん通らないのですが
このクラスをtemplateにするとconstのチェック
が効かなくてコンパイルできてしまいます。
なんでですか?
0185デフォルトの名無しさん
NGNGクラスtemplateのメンバ関数は、必要になるまで定義が実体化されないから。
たぶん、コンパイルできてるソースからは f() の呼び出しがないんでしょう。
0186デフォルトの名無しさん
NGNG実体化されていないから。
0187ルージン
NGNG0188デフォルトの名無しさん
NGNG0189デフォルトの名無しさん
NGNG> 頻繁に構築・解体するコンテナ(例えばループ内の一時変数など)は、 ヒープの分断化を招きますか?
情報足らなさ過ぎ。実測するのが一番。
実測する方法もわからないのなら、そもそも断片化を気にしてもしょうがないし。
0190デフォルトの名無しさん
NGNG配列とかをローカルで宣言するとスタックの浪費になるのでしょうか?
ポインタの配列を宣言して、オブジェクト自体はヒープに
作ったほうがいいのでしょうか?
0191デフォルトの名無しさん
NGNGうん
0192デフォルトの名無しさん
NGNG0193190
NGNGメモリの使用量は同じだと思うのですが、スタックというのは
一定の予約された領域なので、大きなオブジェクトをバシバシ
作ってもいいのかと思いまして。(スタックオーバフローとか
いうのもあるといいますし...)
0194デフォルトの名無しさん
NGNGあまりに大きいオブジェクトの配列はスタック上よりヒープに作った方がとりあえず無難。
それよりその用途ならポインタの配列じゃなくて
ふつうにオブジェクトの配列を動的に作成すればいいんじゃないの?
あとでオブジェクトを一個一個受け渡すのならともかく。
0196デフォルトの名無しさん
NGNGいただきたいのですが、これってただ
コンストラクタを呼んでくれるだけですよね。
であれば
new ((void*)pObj) CWidget;
なんてせずに単に
pObj::CWidget();
としたらいいのになんでわざわざplacement new
という構文が必要なのでしょうか?
実際deleteにはplacement delete(?)みたいな
ものはなくて
pObj::~CWidget();
と書いているのをよく見ますが...
0197デフォルトの名無しさん
NGNGそのpObjってのが何なのかわからん。
ともかく placement new ってのは
引数で与えられた領域にオブジェクトを生成するためのものだ。
コンストラクタを呼び出すだけってのは見当違い。
0198196
NGNGすでに確保されたメモリ上の位置をさしています。
>コンストラクタを呼び出すだけってのは見当違い。
ほかにはどんな作業があるのでしょうか?
0199デフォルトの名無しさん
NGNG>pObj::~CWidget();
>pObjというのはCWidget型のポインタです。
出典はしらんがこんなコード例が載ってるものを信用するな。
>ほかにはどんな作業があるのでしょうか?
注目してるのはオブジェクトを生成する領域だって言ってるだろ。
つーか通常のインスタンス宣言と new や placement new との違いを本当にわかってるのか?
0200デフォルトの名無しさん
NGNGclass AAA
{
AAA() {}
~AAA() {}
};
charbuf[sizeof(AAA)];
AAA*pa = new(buf) AAA;
pa->~AAA();
pa->AAA::AAA();
pa->~AAA();
どっちも同じように走るんだが、何が違うんだろうな?
と書いてて思ったんだが、クラスAAAにplacement newがあったら後者はまずいな。
0202デフォルトの名無しさん
NGNG標準C++ではその様に直接は呼べないだろう。
0203デフォルトの名無しさん
NGNGあるオブジェクトを”割り当て済みのメモリ領域に”生成したいときに使うのが placement new だ。
コンストラクタやデストラクタの振る舞いなんかは二の次。
詳しいことは More Effective C++ の第8項を読むといい。
0204デフォルトの名無しさん
NGNG0205デフォルトの名無しさん
NGNG>pObj::~CWidget();
>pObjというのはCWidget型のポインタです。
っていうかこれ、コンパイル通るの?
0206202
NGNG0207デフォルトの名無しさん
NGNGが作成されるだけで、呼び出しが終わると消滅してしまう。だから
placement newを使うか、コンストラクタを呼び出した結果を*thisに
代入しなければならない。
#include <iostream>
class sample_class
{
public:
int value;
sample_class(int i) {
value = i;
std::cout << "Ctor(int) called\n";
}
sample_class() {
sample_class(10); // ダメダメ
// new (this) sample_class(10);
// *this = sample_class(10);
std::cout << "Ctor() called\n";
}
~sample_class() {
std::cout << "Dtor() called\n";
}
};
int main()
{
sample_class a;
std::cout << a.value << std::endl;
}
0208デフォルトの名無しさん
NGNGコンストラクタからコンストラクタを呼び出して放置すると
メモリリークが起きてしまう。
0209デフォルトの名無しさん
NGNGちごた、これは間違い。デストラクタが正しく書かれていれば一時
オブジェクトの消滅時にデストラクタが呼ばれる。
0210デフォルトの名無しさん
NGNGみたいなやつはあくまでデフォルトの定義。
それはそれで有用ですけど。
placement な operator new は、
例えばこんな風にオーバーロードして、
どこからメモリを確保するかをコントロールしたりとか
けっこういろんなことに使える。
void* operator new(size_t n, Allocator& a)
{
return a.alloc(n);
}
0211デフォルトの名無しさん
NGNG0212デフォルトの名無しさん
NGNG別になくてもおかしくないじゃん。
0213196
NGNG今さらなのですが、間違っていました
× pObj::CWidget();
○ pObj->CWidget();
× pObj::~CWidget();
○ pObj->~CWidget();
0214デフォルトの名無しさん
NGNG言っていることが良くわからない。漏れが言いたかったのは、
foo *p = new foo;
delete p;
とやるなら、
foo *p = new(buf) foo;
delete(static_cast<void *>(0)) p;
とか、
foo *p = new(myalloc) foo;
delete(myalloc) p;
みたいにできた方が自然じゃないか、ってこと。
0215デフォルトの名無しさん
NGNG0216デフォルトの名無しさん
NGNG形だけ見て物を言うと引数つきのデストラクタがないのは不自然みたいな話になるわけだが。
0217デフォルトの名無しさん
NGNGvoid operator delete(void *, void *) {}
void operator delete(void *p, Allocator &a)
{
a.dealloc(p);
}
こんな感じで使えばいいと思う。
0218デフォルトの名無しさん
NGNGnew はコンストラクタじゃないし、delete はデストラクタじゃないよ。
0219デフォルトの名無しさん
NGNG0220デフォルトの名無しさん
NGNG初期化は外部からパラメータ与えてカスタムできる必要があるけど
破棄は(必要なら内部でパラメータを保持していて)
外部からの指定なしにできるべきだという理屈。
そうでないと初期化のパターンすべてについて
破棄を命ずる側がよく知っていなくてはいけなくなるだろ。
この厄介さを考えれば初期化に対する破棄時の仮定は成り立ってもらわんと困る。
#STLのアロケータと同じ類の問題かな
0221デフォルトの名無しさん
NGNGオブジェクトごとに破棄方法を記録するってこと?
それはそれで意味があるかもしれないが、記法の問題を越えるよな。
それに、C++がデフォでその方法を採用するとは思えないから、
(単純なデストラクタ呼び出しに仮想関数呼び出しを付随させるわけにはいかない)
どちらにしてもdeleteと書くたびに、そのメカニズムを使うかどうかを選択せねばならんし。
0222デフォルトの名無しさん
NGNG要するに、
単一の破棄手段と多様な初期化手段の両方を実現するには
どの初期化方法に対しても単一の方法で破棄できるようにするか、
それが嫌ならオブジェクト内部に何らかの形で必要な情報を記録するか
どちらかを選ぶしかないってことよ。
>deleteと書くたびに、そのメカニズムを使うかどうかを選択せねばならんし
これこそ引数つきの delete に対して>>220で指摘した問題なんだけど……
実際現行のC++はそんなものをサポートしていないわけで
0223デフォルトの名無しさん
NGNGどうも話がかみ合っていないと思ったら・・・
>単一の破棄手段と多様な初期化手段の両方を実現するには
>>214は多様な「確保手段」と「開放手段」に似た見た目を与えようとしているのであって、
初期化・破棄についていっているのではない。
0224デフォルトの名無しさん
NGNG0225デフォルトの名無しさん
NGNG確保・解放も含めての話のつもりだったんだけどなあ……。
多様な確保手段に”対応する”多様な解放手段を
常に考慮しなければいけなくなる状況に問題があることはわかってる?
特に解放側から確保側への依存関係を持ち込みたくない状況で。
独自のフレームワークで拡張するのは構わないが、
言語仕様にそんな厄介なものを持ち込まれてはたまらない。
0226デフォルトの名無しさん
NGNGじゃあ、
foo *a = new foo; /* ヒープ */
foo *b = new(buf) foo; /* スタック */
foo *c = new(fixed_alloc<foo>()) foo; /* 固定サイズのメモリ確保ライブラリ */
general_free(a);
general_free(b);
general_free(c);
これがうまく動作するgeneral_freeが実現できるとでも?
0227デフォルトの名無しさん
NGNG>>226
using namespace boost;
shared_ptr<foo> a( new foo );
shared_ptr<foo> b( new (buf) foo, no_op() );
shared_ptr<foo> c( new (fixed_alloc<foo>()) foo, fixed_alloc<foo>::dealocater() );
とかでダメ?
0228デフォルトの名無しさん
NGNG勝手に話を拡張しないでくれ。
placement new は実際にシステムからメモリを”確保”することは行っていないし、
それに対応する”解放”処理もその意味でのメモリの”解放”は行わないってことは踏まえてるか?
いや、俺も>>225で不用意な言い方したんで悪かったと思う。
#placement new でなされる処理をメモリの”確保”と呼ぶのなら
#それに合わせようとしたんだが過度な誤解を与えそうな言い方なのは確かだ。
しかしそこまで基本からはずれた問だと揚げ足取るための例かと邪推してしまうぞ。
0229226
NGNGたとえば、
foo *p = new(myalloc) foo;
p->~foo();
myalloc.dealloc(p);
と書く場合、開放側のコードは確保側に依存しているよな?
(pがmyallocによって確保されたことを期待している)
それを>>214の様に書き直したところで依存性は変わらない。
変わるのは見た目だけで、「'new'と書いたんだから'delete'と書きたい」という
自己満足を満たす以上の何者でもない。(templateが絡むと変わってくるが。)
>>225の言うことは正論で、実行可能だ。(>>227氏thx)
けど、ここでは直接関係しない、ということでいいんじゃないだろうか。
0230デフォルトの名無しさん
NGNGそれってオブジェクトの内部にデアロケータへの参照渡してるんだよな?
(クラスの継承関係に縛られないよう関数ポインタ渡すべきだと思うけど)
それって要するに
あるフレームワークに従って
オブジェクトの内部にデアロケートのための情報を保持させるってことだろ?
>>226だかの placement delete が欲しいと言っている人(達?)の意見は
それは嫌で引数としてアロケータを渡したいと言うもののようだが。
あとついでにshared_ptr は何のために持ち出したか知らないけど。
最後にデストラクタじゃなくて delete 演算子呼んでしまわうから
実際の例としてはまずくない?
0232225(としとく)
NGNGもっかいまとめるね。
placement delete 反対派の俺としては、
(とりあえず自動変数としての宣言、 malloc や、引数なしの new のような”生の”メモリ確保は別物として)
placement new を行った場合に、
その引数に対応する適切な解放処理を解放側が
常に覚えて置いて解放時に記さなきゃいけないような記述はクライアント側のコードの独立性を下げる。
だから、もしデストラクタ以外にそうした独自の解放処理が必要なら
独自のフレームワークに従ってオブジェクトの内部に必要な情報を保持するなりして対応しろ、
ぶっちゃけ、外部から与えるような形式を言語仕様が認めるような形にはするんじゃない(※)と言っている。
もう一方の主張は、
解放処理に余分な指示を与える前提で(※)
どうせ後から解放のための関数呼び出しをするくらいなら
引数つきの delete があった方が構文が統一的になる、というようなものと解釈している。
で、※の部分の前提が目的意識を違わせ、かみ合わなくなっている気がするんだがどうだろね?
0233225
NGNG俺も熱くなりすぎていた。
解放時の独自の関数呼び出しがそこまで重要視されることが想像外だったのね(たぶん)、そこは謝っとく。
それじゃ俺も退散するわ。
0234デフォルトの名無しさん
NGNGplacement new を使えばできてしまうのであれば、
どうせなら直接呼び出せるようにすればいいのに。
構文を統一的にするなら、こっちの方がよっぽどいい。
0235227
NGNGC++でplacement delete演算子を"明示的に"呼び出す構文が
ないのは、禿曰く↓↓みたいなテンプレートを用意すればユーザ定義
できるから、という理由だったはず。
template<typename P1, class T>
void Delete( const P1& p, const T* ptr ) {
ptr->~T(); operator delete( p, ptr );
}
俺はplacement newの方も廃止して、アドレスを渡してコンストラクタを
呼び出す構文"だけ"を用意しとくべきだったと思うのでplacement delete自体に
反対だが、現にplacement newがある以上、対称性からplacement deleteを呼ぶ
構文も存在するべきだというのには全面同意する。
>>230
一個目以外はdelete呼ばないよ。継承関係?関係ない。
0236デフォルトの名無しさん
NGNG#include<iostream>
#include<cstdlib>
struct XX{
int data;
XX(){std::cout << "XX()" << std::endl;}
~XX(){std::cout << "~XX()" << std::endl;}
static void* operator new[] (size_t size){
std::cout << "new XX[]" << std::endl;
void* p = malloc(size); std::cout << p << std::endl;
return p;
}
static void operator delete[] (void* p){
std::cout << "delete XX[]" << std::endl;
free(p); std::cout << p << std::endl;
}
static void* operator new[] (size_t size,void* mem_p){
std::cout << "new (mem_p) XX[]" << std::endl;
mem_p = malloc(size); std::cout << mem_p << std::endl;
return mem_p;
}
static void operator delete[] (void* p,void* mem_p){
std::cout << "delete[] ( p , mem_p )" << std::endl;
std::cout << p << std::endl; std::cout << mem_p << std::endl;
delete [] p; //エラー!!! -> デストラクタがないときは大丈夫 ,G++3.3.1は大丈夫
}
};
0237続き
NGNGXX *x = new XX[5];
delete [] x;
void* mem_p=0;
XX *x2 = new (mem_p) XX[5];
XX::operator delete[] (x2,mem_p);
}
0238デフォルトの名無しさん
NGNGまあそれは置いといて、
static void operator delete[] (void* p,void* mem_p);
の時のpとmem_pの値を見てみろ。
おまえがmallocから貰ったポインタはどちらですか?
0239デフォルトの名無しさん
NGNGnew(mem_p)[]の中では
mem_pは 003707B9
main関数に戻ったときは
mem_pは 00000000
x2 は 003707BC
従って、
static void operator delete[] (void* p,void* mem_p);
のpにx2を渡してるので不整合が起きるみたいです。
デストラクタがある場合は詰め物?があるようで、xの場合も
delete [] x; //はOK
XX::operator delete[](x); //デストラクタがあるとだめ
XX::operator delete[](x-1);//デストラクタがあるとOK
となってしまいました。
>それはplacement newとは言わないんじゃないのか?
なんか根本的に使い方を間違えてるような気がしてきた...
0240デフォルトの名無しさん
NGNGvoid* ひとつを受け取るバージョンは標準ライブラリ<new>で定義されているので、
ユーザーが定義しちゃダメです。
0241デフォルトの名無しさん
NGNGのところにplacement newしちまっているじゃないか。
placement newはすでに領域は確保してあって、そこにオブジェクトを
構築したい時に使う。>>236=237がやりたいような、「自分の希望した
*任意の*アドレスにオブジェクトを生成する」わけではない。
class c{...};
void *buf = operater new[](5 * sizeof(c));
c* pc = static_cast<c*>(buf);
for(int i = 0; i < 5; ++i)
new (&pc[i]) c();
...
delete [] buf;
こんな感じ。というか、More Effective C++読もうや。
0242241
NGNGvoid* operator new(size_t, void* buf)
{
return buf;
}
ここのなかで領域確保するのでは*ない*のです。
0243デフォルトの名無しさん
NGNGv=0;
~((~v) >> 1)
で,intが32ビットなら,
10000000000000000000000000000000 (2)
と,最上位が1のビット列になりますよね
これと同じ事はshortやcharには通用しないんですか?
unsigned short(16bitと仮定)やunsigned char(8bitと仮定)でそれぞれ,
1000000000000000 (2)
10000000 (2)
となることを期待したのですが,参照してみると0だと言われます。
もしかして,ビット演算って1word単位でやるのですか?
だとすると,
10000000000000000000000000000000
で,右から16ビットだけ読んだ場合も,8ビットだけ読んだ場合も
どちらも0となってつじつまは合うんですが。
0244じゅn
NGNG0245デフォルトの名無しさん
NGNGhttp://pc2.2ch.net/pcqa/
0246デフォルトの名無しさん
NGNG計算途中でintになっちゃうYO
最後に代入する部分で警告でてるはずだが。
0247デフォルトの名無しさん
NGNGそそ。整数への格上げ。C++でなくCでも同じ。
0248デフォルトの名無しさん
NGNGv=~v;
v=v>>1;
v=~v;
ならunsigned shortやunsigned charでも最上位が1になるよ。
0249デフォルトの名無しさん
NGNGアメリカの大学でコンピューターサイエンスを
専攻し、昨年卒業したんですが、未だに就職先が
見つかりません。今アメリカではIT業界で職を探すのは
非常に困難です。特に新卒にとっては…。
学校ではJavaでプロジェクトなどやったんですが、
これからはC++に変えたいと考えています。
そこで質問なんですが、C++に将来性はあるのでしょうか?
またC++のどのあたりを勉強したら就職に役立つでしょうか?
あとOSはRedhatのFedoraを使ってるんですが、
コンパイラーは何がいいんでしょうか?
よろしくお願いします。
0250デフォルトの名無しさん
NGNG0251デフォルトの名無しさん
NGNG学者にでもなれば?と思うんだけど。
0252デフォルトの名無しさん
NGNGBYTE b=19;
cout << hex << b << endl;
とやってみたのですが、文字化けしてしまいます。
なんででしょうか?
0253デフォルトの名無しさん
NGNGBYTEってのは中身は(unsigned) charだろ。つまり文字として出力されてしまう。
intに格上げしる。
cout << hex << (b & 0xff) << endl;
みたいに。
0254sage
NGNG論文なり、プログラム作品は持ってる?
0255デフォルトの名無しさん
NGNG> cout << hex << (b & 0xff) << endl;
これでは意図が不明確なので、static_cast<int>(b)の方が良いと思う。
0256デフォルトの名無しさん
NGNG0258252
NGNGintにしちゃうと2バイトなので、0xff00みたいになってしまいました。
「0xff」だけで出力したかったのです。
■ このスレッドは過去ログ倉庫に格納されています