【初心者歓迎】C/C++室 Ver.34【環境依存OK】
>>951 関数レベルで排他制御を行っているような典型的な実装なら、
1) fputs()やfprintf()等を用いて、常に\nで終わる文字列をstdioに
与えるようにする。
2) _IOLBFモードを設定しておく
ことで、出力がcritical section内で完結し、行レベルでatomicになる。
「出力を崩したくない」というのは、通常はそういう意味のはず。
>>954 orz
atan2()
atan2(1,0)(→)は1.570796
atan2(0,1)(↑)は0.000000
atan2(-1,0)(←)は-1.570796
atan2(0,-1)(↓)は3.141593
ちゃんと帰ってきました。
ありがとうございました↓↓
○%f
◎%g
>>934 俺がマルチスレッドでログ出すときは改行までを1回の関数コールでしているな。
2回の関数コールで文字を出したりすると間に別の文字が入るから。
場合によってはミューテックスつきの自作printf風ログ関数を必ず使うようにしている。
# 俺はstd::coutを使わないprintf派。
俺はスレッド単位でログ出力先変える派
スレッド数少ない時限定だけど。
959 :
934:2007/02/18(日) 12:32:42
レスありがとうございました。
マルチスレッドでは単純な文字列の出力でも
同一のリソースにアクセスすることになって面倒なことになるようですね。
勉強になりました。ありがとうございます。
960 :
デフォルトの名無しさん:2007/02/18(日) 13:09:18
お願いします。
下のプログラムは数値を入れ替えるプログラムsort.cである。以下の問いに答えよ。
1.プログラム内の@〜Eに適当な命令を入れてプログラムを完成せよ。ただし@とAは複数の回答がある。可能な限り全て答えよ。
2.変数aがメモリの1000番地に格納されていた。int型が4バイトとすると、変数bは何番地に格納されるか答えよ。
3.関数間のデータ受け渡しにポインタを使うメリットとデメリットを説明せよ。
#include<stdio.h>
/*ポインタ渡しでデータの交換*/
void swap(int *x, int *y);
int main(void)
{
int a=1731, b=935;
int *p1, *p2;
/*ポインタに代入*/
p1=&a;
p2=&b;
printf("初期状態\t");
printf("a=%d b=%d\n",a,b);
swap(@,A);
printf("swap終了後\t");
printf("a=%d b=%d\n",a,b);
return(0);
}
void swap(int *x, int *y)
{
B z;
z = C;
*x = D;
*y = E;
}
宿題スレ池ヴォケ
962 :
デフォルトの名無しさん:2007/02/18(日) 16:34:41
C++で、静的メンバ変数に関数ポインタを指定するにはどうすればいいのでしょうか?
class CA{
public:
static int (*s_m_func1)();
};
int * CA::s_m_func1();
これだと『'CA::s_m_func1()'は'CA'のメンバーではない』って言われて、コンパイルできません。
お助けお願いしますー。
>>962 int (*CA::s_m_func1)() = 0;
>>962 クラス内でstatic int (*s_m_func1)();と宣言したら、
その定義は機械的にstaticを外して名前にクラス名::を付けるだけで作れる。
int (*CA::s_m_func1)();
967 :
デフォルトの名無しさん:2007/02/19(月) 10:45:27
質問です。
placement newのoperator delete(void *p, void* pMemory);で、
渡された*pの型を取得する方法はありませんでしょうか。
operator delete(void *p, void* pMemory)の中でデストラクタを呼んでやりたいのです。
通常のdeleteは、
delete pHoge;
で、Hogeを正しく解体できますし、デストラクタも呼んでいますよね。
これは正しい型情報(pHogeの型のものでしょう。void*にキャストしてから渡すとデストラクタは動きませんから)がdeleteに渡されているからだと思うのですが…。
operator deleteの仕事は、メモリを適切に解放するだけです。もうデストラクタは呼ばれているはず。
>>968 ありがとうございます。
なるほど。確かに通常のdeleteでは、その中に入る前にデストラクタが呼ばれていますね。
となると通常のdeleteはどんなトリックを使っているのでしょうか。
単純に「C++のコンパイラが、そこにデストラクタを呼ぶコードを自動で入れてるんだよ」ということでしょうか。
現在、こんなようなコードになっています。
template<class T>
class CHoge
{
/*省略*/
void test()
T* p;
p = new(pMemory) T;
operator delete(p, pMemory);
}
};
ここには二つの障害があるように思えます。
・Tのデストラクタをどうやって呼び出すか。
・そもそも、Tにデストラクタが無かったらエラーになってしまう。
この2点について、解決できる手法がありますでしょうか?
new演算子の仕事 : operator newでメモリを確保 → コンストラクタ呼び出し
delete演算子の仕事 : デストラクタ呼び出し → operator deleteでメモリ開放
new/delete演算子と、operator new/deleteの意味の違いに気をつけよう、とMore Effective C++で読んだ。
>>970 ありがとうございます。
intなどにもデストラクタが存在するというのは盲点でした。
思い込みにとらわれて、p->~T()がコンパイル通るか試していなかったのが恥ずかしいです。
>>971 なるほど。
その上で、placement new/delete にはnew/delete演算子形式の書式がないので自前でデストラクタを呼ぶ必要があるというわけですね。
ありがとうございます。
思ったとおりの実装ができそうです。
これにて967の質問は解決とさせていただきます。
ありがとうございました。
973 :
デフォルトの名無しさん:2007/02/19(月) 17:55:49
new 演算子で確保した配列メモリのサイズを、
sizeof()で配列のサイズを得るようにするにはどうしたらいいのでしょうか…
ググり方が下手で見つけられませんでした…
出来ればどうググったらよいのかも
もう一つ、reallocの動作をさせるのには、
いったんnewで別に配列メモリを確保して、古い配列メモリをdeleteした上で、
今確保したアドレスを代入するのが最良なのですか?
int *pa = new int[5];
:
:
int *pat = new int[10];
for(i = 0; i <= 5; i++){
pat[i] = pa[i];
}
delete [] pa;
pa = pat;
のような…
このとき最後にdeleteすべきなのはpa? pat?
そんなことしないで、素直にstd::vector使えよ。
質問があります。
class A
{
public:
Test();
};
class B
{
public:
Here();
};
と言うクラスがあるとします。
現在classBのHere()内にいてclassAのTest()関数を呼び出したいのですが、
どうするのが一番良いのでしょうか?
実際は他にもメンバがある状態でTest()のみを使用したいので継承はないかと思ってます。
となると、Here()内でclassAをインスタンス化して呼び出すか、classBに同じ関数を作るという方法を
思いついたのですがどうなのでしょうか?
よろしく御願いします。
A::Testというのは普通Aのインスタンスを弄ると想定されるわけだが、
B::Hereにおいては、Aのインスタンスの変更以外の作用が欲しい、というところか?
A::Testのうち、インスタンスに依存しない部分を切り出すのはどうだろうか。
977 :
975:2007/02/19(月) 19:02:09
説明不足ですいません。
A::Test()はclassAのメンバを弄るのではなく、引数で複数の変数ポインタを渡し
それらを計算してアドレスを返すという関数なんです。
classAのメンバ関数内でで数回呼び出すのでclassAのメンバ関数とした訳ですが、
構造的に悪かったですか?
弄らないならstaticにでもしとけ。
979 :
973:2007/02/19(月) 19:08:05
>>974 stringとかvector使うと
INIファイルを弄るあたりが面倒になるので、あまり使いたくないのですが…
たとえばGetPrivateProfileStringやGetWindowTextなどでバッファは配列アドレスを渡す必要があるので…
980 :
975:2007/02/19(月) 19:10:18
>>978 あ、そういう手がありましたね。有り難うございました。
>>979 vectorでできないわけないだろ・・・
ジェネリック医薬品なテンプレート定義
何のための&vector[0]だよ。
>>979 std::vectorの要素はメモリ上で連続していることが保障されていて、
真にmalloc/realloc/freeなどと同じように動的メモリとして使える。
983の言うとおり先頭要素へのポインタという形で取り出せばよい。
ただしイテレータはポインタで実装されているとは限らないので、
begin()は狩にお前使っている処理系で使えたとしても使うべきでない。
std::vector<char> v(0x1000, '\0');
std::fgets(v, v.size(), stdin);
std::vector<char>::iterator pos = std::find(v.begin(), v.end(), '\0');
std::string line(v.begin(), pos);
とかキモいな。
どうせC関数とインタフェースするところなんて、多かれ少なかれ汚いんだから、
適材適所で使い分ければいいんでねーの?
char v[0x1000];
std::fgets(v, sizeof v, stdin);
std::string(v);
のが記述が簡単で効率もいいだろ。
986 :
985:2007/02/19(月) 20:24:42
ごめん
- std::fgets(v, v.size(), stdin);
+ std::fgets(&v[0], v.size(), std::stdin);
なんでstd::findするの?string(&v[0])でいいじゃん。
vector<char>をNUL埋めする意味もわからん。
そもそもなぜstd::getline使わない
>>987 どうせ省略しても'\0'で初期化されることに変わらない気がする
989 :
973:2007/02/19(月) 20:40:13
…動的メモリとして使えるコトを全く知りませんでした…
vectorなんて使い必要ないじゃんとか考えていて……
バカなことばっかですいません。
iostreamは遅い、というのが定説だからじゃないの。
>>990 それだったらOSのAPIを呼べよと俺は思ってしまう。
993 :
985:2007/02/19(月) 21:02:05
>>987 前者はその通りだな。
後者は、予め領域は確保しなきゃならんでしょ?その副作用。
malloc()のように「確保だけする」手段ってstd::vectorにはないよね?
指定しなくとも、必ず何かデフォルト値で埋められる。
つまり効率が少なくともcalloc()並に落ちるということ。
auto配列とは比較にならないね。
>>988 単にC関数とインタフェースする例だよ。
別にfgets()である必要は全く無い。
要素数固定でよければ、boost::arrayがいいと思っていた時期があった。
995 :
973:2007/02/19(月) 21:07:32
>>991 そもそもvectorの根本的な使い方わかってなかったみたいです…
ともかく、おつきあいいただきありがとうございました。
reserve()の立場は
>>996 size()で得られるインデックス以上の要素にアクセスしてはならない以上、
固定長のバッファが欲しいときに使う性質のものではない。
組込みのauto配列はコンパイル時固定サイズだが、それでは困るって場合には
alloca()使えばいい。
移植性にやや難があるけどな。
allocaは不足しても延ばせないからなー
つ std::get_temporary_buffer
1001 :
1001:
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。