【初心者歓迎】C/C++室 Ver.48【環境依存OK】
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2008/02/05(火) 01:18:41ただしその場合、質問者は必ず環境を書きましょう。
※sage禁止です(と代々スレに書いてありますが自己判断で)。
【前スレ】
【初心者歓迎】C/C++室 Ver.47【環境依存OK】
http://pc11.2ch.net/test/read.cgi/tech/1200464091/
【アップローダー】(質問が長い時はココ使うと便利)
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm
0757デフォルトの名無しさん
2008/02/16(土) 10:55:58boost::array<int,4> d;
std::vector<d> data;
と定義だけはエラーが出ないのはいいのですが
実際はどのように使えばいいのでしょうか。
d[0]=0;
d[1]=1;
d[2]=2;
d[3]=3;
data.push_back(d); //この部分がエラー
としてもコンパイルエラーが出ます。
0758デフォルトの名無しさん
2008/02/16(土) 11:06:03すいません。できました。別に原因があったようです。
0759デフォルトの名無しさん
2008/02/16(土) 11:31:11class Test{
public:
static int ary[4];
};
int Test::ary[] = {0,1,2,3};
int main(){
printf("%d\n", Test::ary[2]);
}
すみません。上記のように1次元配列だと初期化できるのですが
2次元配列にするとどう記述しても初期化できません。
例えば
static int ary[2][4];
};
int Test::ary[] = {0,1,2,3, 5,6,7,8};
にすると
error C2040: 'ary' : 'int []' は 'int [2][4]' と間接操作のレベルが異なります。
となりますし
多次元配列のメンバ変数を初期化する方法はないものでしょうか?
0760デフォルトの名無しさん
2008/02/16(土) 11:42:03int Test::ary[] = {0,1,2,3, 5,6,7,8};
これはおかしいよ。
int Test::ary[2][4] = { { 0,1,2,3 }, {5,6,7,8} };
とかじゃないの?
0761デフォルトの名無しさん
2008/02/16(土) 11:51:33有難うございます。上手くいきました。
int Test::ary = { { 0,1,2,3 }, {5,6,7,8} };
や
int Test::ary[][] = { { 0,1,2,3 }, {5,6,7,8} };
や
int Test::ary[0][0] = { { 0,1,2,3 }, {5,6,7,8} };
で試してみて上手くいかなかったのでどうやるのかと思っていました。
[2][4]と書けば良かったのですね。
0762デフォルトの名無しさん
2008/02/16(土) 12:04:02厳密には寿命と記憶期間は別物だが、
大抵の人は普段は記憶期間の意味で寿命という言葉を使う。
0763デフォルトの名無しさん
2008/02/16(土) 12:16:550764デフォルトの名無しさん
2008/02/16(土) 12:23:500765デフォルトの名無しさん
2008/02/16(土) 12:43:32以下のコードを実行したとき、throw(�A)のあとで
TTestクラスのデストラクタが呼び出されると思っていたのですが呼び出されません。
auto_ptrってこういうものなのでしょうか?
TTest* TTest::NewL()
{
std::auto_ptr<TTest> self(new TTest());
throw 1; // �A
return self.release();
}
0766デフォルトの名無しさん
2008/02/16(土) 12:47:54例外が捕捉されなければ呼ばれないかもしれない(環境依存)。
auto_ptr の問題じゃなくて、C++ の仕様の問題。
0767デフォルトの名無しさん
2008/02/16(土) 12:48:27catchしたか
0768765
2008/02/16(土) 12:53:01ちなみに、std::auto_ptrの部分を自作のsmart_ptr(スマートポインタの解説サイトを参考に作成)
にした場合はきちんとデストラクタが呼ばれました。
コンパイラはBorland C++ Compiler 5.82 なのですが、これのauto_ptrがポンコツなのかも…
0769デフォルトの名無しさん
2008/02/16(土) 12:58:410770デフォルトの名無しさん
2008/02/16(土) 13:01:090771765
2008/02/16(土) 13:12:49auto_ptrのソースをちょこっと改造して試したところauto_ptrのデストラクタ自体が呼ばれてないようでした。
ただ、gccだと正常に呼ばれるとのことなのでBCCが悪いということで解決します。
どうも、ありがとうございました。
0772デフォルトの名無しさん
2008/02/16(土) 13:16:48他の所でも沢山困る所があるかもしれないぜ。
0773デフォルトの名無しさん
2008/02/16(土) 13:19:46どう表示される?
#include <iostream>
#include <memory>
class Test {
public:
Test(int n) : n(n) { }
~Test() { std::cout << "~Test(" << n << ")" << std::endl; }
static Test* New() {
Test test1(1);
std::auto_ptr<Test> test2(new Test(2));
throw 1;
return NULL;
}
private:
int n;
};
int main() {
try {
Test* test = Test::New();
test = test;
} catch(int n) {
std::cout << "catch" << std::endl;
}
return 0;
}
0774デフォルトの名無しさん
2008/02/16(土) 13:26:09BCCで試したところ、以下のように表示されました。
やはりtest2が削除されないようです。
~Test(1)
catch
>>772
確かに…引き続き調査はしてみます。
0775デフォルトの名無しさん
2008/02/16(土) 13:27:49それが表示されるかチェックしてみれ。
0776デフォルトの名無しさん
2008/02/16(土) 13:56:280777デフォルトの名無しさん
2008/02/16(土) 14:00:52あるけどおまえにはそれすら無意味
0778デフォルトの名無しさん
2008/02/16(土) 14:28:58staticな変数の生存期間はそのプログラムが起動されてから終了されるまで。
絶対に外部から参照される恐れが無い場合でもなければ、使い回しはできない。
例えば、strtok()やlocaltime()は内部のstaticな領域を返すように実装されていることが多い。
従って、その関数を呼び出した先で参照する可能性があるからコンパイラはこれを取り除くことができない。
0779デフォルトの名無しさん
2008/02/16(土) 15:07:48そのときの話をしてるんだが?
アドレス取られたら削除できないのはあたりまえ。
また、絶対に外部から参照されないケースなんてほとんどないので、
大概の実装ではそんな最適化をしていないと思う。
問題にしているのは、規格としてそう言うことをしていいかどうか
だよ。
0780デフォルトの名無しさん
2008/02/16(土) 15:23:33規格を云々したいのなら折角そういうスレがあるんだからそちらへどうぞ。
0781デフォルトの名無しさん
2008/02/16(土) 15:25:24仮にあったとしても、779の状況では、
プログラム上から異なるアドレスであることを確かめるすべはないと思うけど。
0782デフォルトの名無しさん
2008/02/16(土) 16:08:56それらは同じアドレスに置いても構わない。
また、"abc" というのと "bc" というのがあった場合、
"bc" のアドレスが "abc" + 1 であっても構わない。
0783デフォルトの名無しさん
2008/02/16(土) 18:00:20f_point square[4]; // 正方形の頂点が入る
for(float angle=0;angle<PI*2;angle+=PI/16){
...
}
構造体squareに正方形の頂点4点の平面座標が入るとして、
その正方形の中心を軸に回転させるには
forの中でどういう風に書けばよいでしょうか?
0784デフォルトの名無しさん
2008/02/16(土) 18:08:56正方形を中心と、どれか1つの頂点の角度とで扱えばいいんじゃね?
0785デフォルトの名無しさん
2008/02/16(土) 18:13:27宿題スレでもいけばいいんじゃね?解答もらえるよ
x, yをx + y iの複素数とみなして
cosθ + i sinθを掛けた値の実部と虚部を取る
計算を行うようにするとか
x * cosθ-y * sinθ, x * sinθ+y * cosθ
になるんじゃなかったかな多分
0786デフォルトの名無しさん
2008/02/16(土) 18:15:37x度回転するには、σ(n) = θ + (x+90n) *π/360
px + r cosσ(n) , py r sinσ(n)に変換する
0787デフォルトの名無しさん
2008/02/16(土) 18:17:45誤差で境界条件が重い通りにならないかもしれないんだから。
0788デフォルトの名無しさん
2008/02/16(土) 18:19:30○構造体f_pointの配列square
つ[アフィン変換]
0789デフォルトの名無しさん
2008/02/16(土) 18:22:09をかければいいんだろ
0790デフォルトの名無しさん
2008/02/16(土) 18:27:16なんかビミョーな違和感
0791デフォルトの名無しさん
2008/02/16(土) 18:38:47f_point center = average(square, square + 4);
for (int angle = 0; angle <= 360; ++angle) {
for (int ic = 0; ic < 4; ++ic) {
print ([square[ic].x square[ic].y] - [center.x center.y]) * [cos(angle * rad) sin(angle * rad); -sin(angle * rad) cos(angle * rad)] + [center.x center.y];
}
}
// 要は、正方形の中心が原点になるように移動して、回転してから再び移動(≒>789)
0792デフォルトの名無しさん
2008/02/16(土) 18:43:04ほんとごめんなさい、よく読んでませんでした
原点中心回転してました
0793デフォルトの名無しさん
2008/02/16(土) 19:51:23char a ;
を、関数の中で数値に変換して
int a ;
にしたいんだ
同じ変数名aなんだけど
char → int
ってできますか?(´`)
0794デフォルトの名無しさん
2008/02/16(土) 19:55:180795デフォルトの名無しさん
2008/02/16(土) 20:00:53それだと1文字だろうし最初からintで受け取ればいい
0796デフォルトの名無しさん
2008/02/16(土) 20:01:01文字とか文字列を数値にしたいとかじゃなくて
char型変数を名前そのままにint型変数に変えたいんだな?無理です
0797783
2008/02/16(土) 20:04:07ありがとうございます。無事できました。
float fCenterX = ( x1 + x2 ) / 2;
float fCenterY = ( y1 + y2 ) / 2;
float fR = ( float )hypot( fCenterX - x1, fCenterY - y1 );
float fX[] = { x1, x2, x1, x2 };
float fY[] = { y1, y1, y2, y2 };
float fA_[] = { 7, 5, 1, 3 };
for( int i = 0; i < 4; i++ ){
fX[ i ] = fCenterX - fR * cos( fAngle + D3DX_PI / 4 * fA_[ i ] );
fY[ i ] = fCenterY + fR * sin( fAngle + D3DX_PI / 4 * fA_[ i ] );
}
0798デフォルトの名無しさん
2008/02/16(土) 20:18:21重くなるかな?と思ったら、逆に軽くなりましたねw
やっぱVistaとVS2005との相性が悪かったんでしょうか。
感激です。
0799デフォルトの名無しさん
2008/02/16(土) 20:22:360800デフォルトの名無しさん
2008/02/16(土) 21:01:00単純に2005より最適化されて軽くなっただけ
0801デフォルトの名無しさん
2008/02/16(土) 22:39:14親クラスに作ったstatic変数は、
全子クラスで共有するのでしょうか?
それとも、各子クラスに一つずつ、
オーバーライドした同名のstatic変数ができるのでしょうか?
それとも、static変数は継承できず、
各子クラスで同名のstatic変数を宣言しなければいけないのでしょうか?
0802デフォルトの名無しさん
2008/02/16(土) 22:51:28その結果の通りだ。
0803801
2008/02/16(土) 22:53:37めんどくさくて質問してしまいました。すいません。
試してみます。
0804デフォルトの名無しさん
2008/02/16(土) 22:54:13その中では全子クラスに共有というのが一番近いが、
正確には親クラスにしか存在しない。
ただし、protectedやpublicなら子クラスからでもアクセスできる。
0805デフォルトの名無しさん
2008/02/16(土) 22:56:06という質問なら良し。
0807801
2008/02/16(土) 23:02:26ありがとうございます。
具体的に何をやりたかったかというと、
各子クラスのstatic変数にアクセスするstatic関数を、
親クラスに作りたかったのです。
static変数は各子クラス別々のものを使うけど、
それに対して行う処理は全子クラスで共通だったので。
0808デフォルトの名無しさん
2008/02/16(土) 23:05:56本当にその実装方法しか無いんけ?
static 変数は基本的には再利用性を阻害する癌のような物だから、
ないならないで済むのが一番いいのだが。
まあ、使い勝手と天秤にかけたら static 変数に軍配が上がることもあるけど。
0809デフォルトの名無しさん
2008/02/16(土) 23:19:34template<typename T>
class Base
{
//T::Hogeを使う。
};
class Derived : public Base<Derived>
{
public:
static const int Hoge = 10;
};
0810801
2008/02/16(土) 23:22:31説明しづらいのですが、
シューティングゲームで、敵ユニットを表すクラスを作っています。
まず親クラスUnitがあって、敵の種類ごとにUnitを継承したクラスを作っています。
敵一匹がUnitのインスタンスになるのですが、
ユニットに使う画像はインスタンスごとに持っている必要は無く、
ユニットの種類ごとにあればいいので、Unit各子クラスのstatic変数にしてます。
だけど、その画像に対して行う処理は、
敵の種類に関わらず全クラス共通なので、親クラスのUnitに作りたい。
そんな感じです。
C++も、ゲーム作るのも初めてなので、
もっといい実装方法案があったら、教えてもらえると嬉しいです。
0811デフォルトの名無しさん
2008/02/16(土) 23:25:32とりあえず一旦動くところまで組み上げてしまうんだ
どんなにソースコードが汚くなろうとも
その後で、こうしているんですが
もっと良い方法はありませんか?
と質問するヨロシ
0812デフォルトの名無しさん
2008/02/16(土) 23:31:23画像が要らなくなった時に破棄したくなったとき少し面倒かもね。
俺なら敵ユニット作成クラスと画像管理クラスを作るかな。
でも、とりあえずそれで組んでみてもいいんじゃね。
0813デフォルトの名無しさん
2008/02/16(土) 23:31:50参考書に
array[index]の結果は*((array)+(index))と同じなので
char ch = p[3];
と
char ch = 3[p];
(pはポインタ)
は、同じ処理だと書いてあったのですが、データ型がintの場合は3が12バイト分になってdoubleの場合は3が24バイト分になるはずなので
一概に「3+pに格納されてるアドレスの数値」って言えない気がしたのですが何か考え方が間違っているのでしょうか?
0814デフォルトの名無しさん
2008/02/16(土) 23:33:590815デフォルトの名無しさん
2008/02/16(土) 23:35:29ポインタとアドレスは違う(似ているからややこしいが)
char a[2];
double b[2];
printf("%p %p\n", &a[0], &a[1]);
printf("%p %p\n", &b[0], &b[1]);
0816デフォルトの名無しさん
2008/02/16(土) 23:40:10p が char* なら p + 3 は 0xb1832103 に、
p が int* (int は4バイトとする)なら p + 3 は 0xb183210c に、
p が double* (double は8バイトとする)なら p + 3 は 0xb1832118 になる。
だから、一概にそう言える。
0817801
2008/02/16(土) 23:41:36ありがとうございます。
テンプレートというのは知りませんでしたが、使えそうな気がします。
>>811
確かにそうですね。
後から実装を作り替えるのは手間ですが、
実際動くと、モチベーション上がりますよね。
>>812
画像破棄用の全画像リストは、ユニットとは別に作ってます。
ユニットは敵の種類ごとに画像をロードすると同時に、
画像マスターリストにロードした画像を登録して、一括で破棄してます。
0818デフォルトの名無しさん
2008/02/16(土) 23:45:31なるほど。
あと、ある敵ユニットから派生して新しい敵を作りたい時に困るかもね。
そういうことがあるかどうか、だが。
画像オブジェクトへの参照のようなもの、
あるいは画像リストのインデックスのようなものを保持させるなら、
ユニットごとにそういう情報を持っていたのでも
大した容量圧迫にはならないと思う。
0819813
2008/02/16(土) 23:49:56腑に落ちました。ありがとうございましたm(_ _)m
0820デフォルトの名無しさん
2008/02/17(日) 00:00:03static変数の初期化は各子Unitじゃなくて、別の何か(親Unit?)がしてるの?もしそうなら
設計ミスだと思うよ。
それじゃstatic変数をグローバル変数として使ってるのとかわりがない。
static変数の初期化は子Unitが行うべき。
ところで
>各子クラスのstatic変数にアクセスするstatic関数を、
これがイメージできないんだけど、具体的に何をする関数を作りたかったの?
parentStaticFunction( childStaticImage );
みたいな感じで子Unitが呼び出しちゃダメなの?
0821デフォルトの名無しさん
2008/02/17(日) 00:03:45あるいは仮想関数にするか。
0822デフォルトの名無しさん
2008/02/17(日) 00:13:42開発環境:Winは.net2002 + SDK, MacはCordWarrier pro 5 + Carbonです。
0823822
2008/02/17(日) 00:15:400824801
2008/02/17(日) 00:18:43ユニットクラスが持ってるのは画像のポインタなので、容量はたいしたことないと思いますが、
大量に敵が出るので、オブジェクトごとにそれを作る負荷がどんなもんか想像つかなくて、
なるべく共有できるものは共有しようと思いました。
>>820
初期化はちゃんと各子Unitでやってます。
>parentStaticFunction( childStaticImage );
これはできます。
今までJavaしかやったことなくて、決まりきった引数を指定するのが嫌だったのです。
神経質ですいません。
でも、割り切ってこれが一番現実的でいいかもしれませんね。
>>821
>画像管理クラスに対する処理
ありがとうございます。
難しそうですが、それは一考の価値があるかも。
0825デフォルトの名無しさん
2008/02/17(日) 00:23:251億体出るなら馬鹿にできないし
0826デフォルトの名無しさん
2008/02/17(日) 00:24:10のようなことをするしかない気がするんだけど。
0827デフォルトの名無しさん
2008/02/17(日) 00:26:03敵5000体出した所でたった20キロバイト。
これ以上敵を出そうとしても処理落ちひどくて無理だでよ(5000体でもキツいだろう)。
誤差の範囲だ。
0828デフォルトの名無しさん
2008/02/17(日) 00:26:55QiuckDrawのPenModeかなぁ。
ttp://developer.apple.com/DOCUMENTATION/mac/QuickDraw/QuickDraw-59.html
ttp://developer.apple.com/DOCUMENTATION/mac/QuickDraw/QuickDraw-75.html
0829801
2008/02/17(日) 00:29:38>1億体
出ませんw 最大でも1500くらい。
>>826
そういえばJavaでstatic変数をオーバーライドなんてやったことなかったですw
Javaに比べて、C++とWin32APIは引数が多くて嫌だなと、なんとなく思ってただけです。
すげー悩んで試行錯誤しながら、今の形になってきたんですが、
要件を聞いただけで、ぱっと思いつくなってみんな凄いですね。
破棄のための画像管理クラスなんて最初全然考えてなくて、後から作りました。
0830822
2008/02/17(日) 00:58:39PenModeの8つのモードすべてで試したのですが駄目でした。私もPenModeだと思ったんですが。。。
SetROP2のように前景モードで動作するのではなく、GrafPort自体に描画しているようです。
Carbonを使い始めて2ヶ月程度なので、間違いがあったらごめんなさい。
0831デフォルトの名無しさん
2008/02/17(日) 01:47:40んー。前景と背景の合成方法を設定するAPIだから、やってることは同じだと思うけどね。
PenModeは現在のGrafPortに対して作用するんで、SetPortPenModeでポートを指定したらどうかな。
もうやってるかもしれないけど。
俺はCocoaな人なので、あんまり力になれなくてすまん。新・mac板の方が詳しい人いるかもね。
0832822
2008/02/17(日) 12:07:03書いてなかったけど、ラバー バンディングを実行したくて行き詰まってしまいました。
マウスをドラッグしている間、直前に描かれた線を上書きで消して新しいPointに対する
線を描くという動作なんですが、最後にInvalWindowRectするとエンティティ自体は
正常に描かれます。エンティティ自体を移動させても余計に描画された線は消えます。
長くなって済みません。Macの開発環境がまだ自宅にないので明日会社でSetPortPenMode
を適用してみます。ありがとうございました。
0833デフォルトの名無しさん
2008/02/17(日) 12:19:092008/02/17 11:53:59
みたいな日付をint型もしくはunsigned int型にしたいのですがどうすればいいのでしょうか?
秒に変換する事も考えましたが2008*365*24*60*60だとintに収まり切りません。
そのまま文字列で保存すればいいかもしれませんが、
この値をstlのmapのキーにしてソート等を行いたいので文字列だと遅そうなのでint型にしたいです。
スレ違いかもしれませんが何か良い方法があれば教えてください。
お願いします。
0834デフォルトの名無しさん
2008/02/17(日) 12:27:220835デフォルトの名無しさん
2008/02/17(日) 12:34:170836デフォルトの名無しさん
2008/02/17(日) 12:34:32年だけ別にしたら?
struct Date
0837デフォルトの名無しさん
2008/02/17(日) 12:35:41struct Date
{
unsigned int year;
unsigned int sec;
};
みたいに。
0838デフォルトの名無しさん
2008/02/17(日) 12:39:52それをそのまま使おうとしてmapで使えないと質問しにくるとみた
0839833
2008/02/17(日) 12:53:46>>834
自分の環境では__int64使えるみたいだったけど、他のPCで実行したらどうなるか分からないので今回は辞めておきます。
>>835
えっと、どういう意味ですか?
>>836-838
なるほど。そういう手もありましたね。
つまり、比較演算のオペレーターを自作するって事ですよね?
ちょっと、その方法でやってみます。
0840デフォルトの名無しさん
2008/02/17(日) 12:56:410841デフォルトの名無しさん
2008/02/17(日) 13:05:02暦法の微妙な問題に足突っ込みたくなければ全部秒で表した方が無難
しかし使えるならboost::gregorian使っとくのが楽ではある
0842デフォルトの名無しさん
2008/02/17(日) 13:06:27年が1999年以降しかなくて、2099年までしか使わないのであれば
unsigned intでも収まりそうな気がする
0843デフォルトの名無しさん
2008/02/17(日) 13:10:27通算秒
time_t
0844デフォルトの名無しさん
2008/02/17(日) 13:21:04まずはこれで実装してみて、ほんとにそこがネックになってるなら
いろいろ工夫すればいいと思う。
0845833
2008/02/17(日) 13:55:31キーを構造体にするという>>836-837さんのやり方で出来たので今回はこれでいこうと思います。
>>840,843
time_tと言う変数は知りませんでした。今度調べてみようと思います。
>>841
閏秒の問題は考えてませんでした。
そこまでの制度の秒を管理する訳じゃないので今回はこれで・・。
boost::gregorianと言うのも知らなかったので調べておきます。
>>842
確かに年を3桁にすれば入りそうですね。
そんなに広い範囲の年を扱う訳じゃないのでそれで良いかもしれませんがなんかなw
>>844
一応、キーをUINT, string, struct{UINT, UINT}の3パターンで挿入の時間を計ってみた所、
UINT > struct{UINT, UINT} > stringの順で速かったです。
Cは文字の扱いにあまり優れていないと聞いたことがあるのでそう思ってました。すいません。
とりあえず、これで解決とさせて頂きます。ありがとうございました。
0846デフォルトの名無しさん
2008/02/17(日) 14:05:060847デフォルトの名無しさん
2008/02/17(日) 14:08:390848デフォルトの名無しさん
2008/02/17(日) 14:13:500849デフォルトの名無しさん
2008/02/17(日) 14:20:16素直に__int64使ったほうがマシだと思うけど
0850デフォルトの名無しさん
2008/02/17(日) 14:21:270851デフォルトの名無しさん
2008/02/17(日) 14:26:080852デフォルトの名無しさん
2008/02/17(日) 14:37:031970年の1月1日とかからカウント始めれば、精度が秒くらいならunsignedな32bitで十分収まる。
0853デフォルトの名無しさん
2008/02/17(日) 14:42:10うまくコンパイルがとおらないので、教えてください。
fedora core1で、コマンドラインからc++でコンパイルしてます。
---------------------
#include <stdio.h>
#include <openssl/rc4.h>
int main(){
RC4_KEY key1;
const char *keystring = "HOGEHOGE";
RC4_set_key(&key1, 4, (unsigned char *)keystring);
return 0;
}
---------------------
コンパイルすると下のようになります。
----------
/tmp/ccuOdmEl.o(.text+0x30): In function `main':
: undefined reference to `RC4_set_key'
collect2: ld はステータス 1 で終了しました
-------------
未定義の関数を用いているようなエラーですが、
rc4.hをインクルードしているのですが、
どこがいけないのでしょうか?
0854デフォルトの名無しさん
2008/02/17(日) 14:43:570855デフォルトの名無しさん
2008/02/17(日) 14:48:34コマンドラインから
%c++ main.cpp
としました。
すると、上記のエラーが表示されます。
0856デフォルトの名無しさん
2008/02/17(日) 14:51:51■ このスレッドは過去ログ倉庫に格納されています