【初心者歓迎】C/C++室 Ver.76【環境依存OK
前スレで次スレと称して前スレを貼るなしw
リスト構造からやり直しだなw
ノード数が1の循環リストなんじゃねのか
おいなんだprotectedって
誰かわかりやすく図示してくれ図示
∩
/~~\ ←protected 明るい家族計画
( ゚ )
|o |
|0 |
(ニニニ)
( ・∀・)
) (
(__Y_)
protected
派生先からはpublic
外からはprivate
>>6 あーそれだけなのか
なんで皆難しく説明するのかねぇ?
publicはpublic
privateはprivate
でも 子供に秘密を教えた時があるよね。
そん時が protected
家族限定みたいな。
>>7 みんな俺頭いいだお?すごいだろぉ?をしたいものさ
#define private public
#define class struct
クラスを参照渡しで引数として渡しているのですが特にコンストラクタなどがない場合関数内でクラス宣言した方が速いですかね?
>>12 void func(const hoge& arg)
{
}
よりも
void func()
{
hoge h;
}
ってこと?
そういうことです。どっちが速いのかなって
>>14 速度どうとかより何かを受け取るために必要な引数じゃないの?
void func1(const hoge&){...}
{ hoge h; func1(h); }
なら
void func2(){hoge h;...}
{func2();}
のほうが速いよ
>>15 クラスの関数しか使わないので中で宣言してもやることが変わらないんですよ
>>16 中で宣言した方が速いのですか。これは書きなおしだなー
ありがとうございます
#include <fstream>
int main(int argc,char* argv[])
{
std::ofstream ofs("text.txt");
for(int i = 0 ; i < argc ; ++i)
{
ofs << argv[i] << std::endl;
}
return 0;
}
このプログラムになんらかのファイルをドラッグ&ドロップして起動しました。
しかしなぜか同じディレクトリ以外からドラッグしたファイルの名前は
textに出力されません。なぜでしょうか?
VS2010です
ドラッグドロップしたファイルの置いてあるディレクトリに
text.txt が出力されているとか
>>19 ほんとだ・・・気づきませんでしたありがとうございます
放り込むファイルの場所がカレントになるのか。
へー…前からそうだっけ?
>>21 俺も実行ファイルと同じ場所になるような気がしていたが、今確認したら
Win 7 sp1: ドロップしたファイルの場所
Win XP sp3: ユーザープロファイルの場所
スレッドの同期って、共有する変数に対して
1つのスレッドだけが書き込みを行って
他のスレッドは読み込みだけの場合でも必要なのですか?
>>23 書き込み同士は排他が必要だが、読み込み同士は排他は不要。
問題は書き込み中に読み込み、あるいは読み込み中に書き込み、だが、これは書き込み/読み込み対象のオブジェクトが小さければ不要なこともあるかもしれない。
変数の書き換え操作にもともとアトミシティがあるなら不要。
書き換え途中の変数にアクセスしても泣かないなら不要。
それ以外は必要。
メモリバリアしてやらないと、あるCPUが書き込んだ情報は他のCPUが読めないだろ。
x86-64限定ならたぶんOK。
main.cppがごちゃごちゃしてきたので、ヘッダファイルとそれに対応したソースファイルに分割中なのですが、
インクルードが上手くいかず、
〜〜〜 定義されていない識別子です。
というエラーが沢山出て頭が爆発しそうです。
ヘッダファイルで宣言、定義した変数、定数、関数、クラスをそのまま対応したソースファイルや
main.cppで使用する方法はありませんか?
29 :
23:2011/08/16(火) 01:55:03.81
返答ありがとうございます、常に排他が必要ではないのですか。
書き込み中に読み込みが行われた場合の問題というのは、
書き込み前の値を読み取られる可能性がある、というだけなのでしょうか?
>>29 >>25の書いてる通り、アトミシティーがあるならそう。
無ければ何が起こっても文句は言えない。
>>29 環境によっては、例えば0xffffから0x10000に書き換える瞬間に読み出した結果が
0x1ffffになるかもしれないし、0になるかもしれない。もしかしたら、0x100ffになるかもしれない。
32 :
23:2011/08/17(水) 03:09:05.42
>>30 >>31 ありがとうございます、環境によっては危険なことになるようですので、
同期はとるようにします。
大変勉強になりました、返答を下さった方々、もう一度ありがとうございます。
>>27 VisualC++なら項目の追加で分割したcppやhを全てプロジェクトの中へいれる。
あと、C++はコンパイルすると関数名を勝手に変えてしまうので、ソースを分割するとそれまでリンク出来ていたものが出来なくなるから、hファイルにおまじないを書かないといけない。
34 :
デフォルトの名無しさん:2011/08/17(水) 22:07:46.93
int
main(int ac, char **av)
{
const int N = 1000000;
int *alloc = new int[N];
memset(allc, 0, sizeof(alloc) * N);
return 0;
}
これを実行すると、セグメンテーションエラーになります。なにか間違ってますか?
$ ./a.out
Segmentation fault
$
環境は64ビットのUbuntuです。
sizeof(*alloc)かsizeof(int)にしないとダメなんじゃないの?
36 :
デフォルトの名無しさん:2011/08/17(水) 22:16:38.94
>>35にすれば直らなくもないけど、バイナリでゼロ初期化するセンスがおかしい。
intの配列を全要素0で初期化したいんだから、
std::fill_n(&alloc[0], N, 0);
が素直。
ゼロ初期化なら、
int *alloc = new int[N]();
とかで出来なかったっけ
42 :
デフォルトの名無しさん:2011/08/18(木) 21:18:39.03
auto& shortname = very.longlong.name;
みたいにして長い変数名を短縮する目的で参照を使うのは
行儀が良くないですか?
少なくともプロは使わない、とか、コーディング規約で普通禁止される、
とか、そういう意見があれば教えてください。
>>42 まず長い名前になること自体どっかおかしくね?という視点は必要な気がする。
適切にクラス、関数が切り分けられていないかもしれない。
後は生存期間の問題がなければ個人的には有り。
44 :
42:2011/08/19(金) 00:53:45.00
>>43 回答ありがとう。
長い名前は自分が作ったわけではないライブラリのAPI名でして。
安易に参照作って生存期間でハマるのは前にやって懲りたので、
引き続き気をつけます。
>>44 --
{
// 長い処理
auto & shortname = very.longlong.name; // shortnameも充分長ぇよ
// ある程度長い処理
// veryの寿命が尽きた後
}
--
よりは
--
{
// 長い処理
{
auto & shortname = very.longlong.name; // shortnameも充分長ぇよ
// ある程度長い処理
}
// veryの寿命が尽きた後
}
--
のようにブロックにしてスコープを狭くすれば少しだけ安心感が増すかと。
wstring *p;
wstring s;
*p = s;
sの方が*pより長いときに、領域外アクセスで落ちることはありますか?
>>46 pは何も指していないが大丈夫か?
単に代入のことを言っているなら、
小さければ内部配列は拡張されるから安心汁
>>46 pは実体が確保されていないので、*p=sは常に問題のあるコードです。
不正メモリアクセスで落ちたらラッキー
クラスの中で、構造体テンプレートをメンバーに持つってありですか?
設計的におかしいと思うのですが?
rebindのことだな!
>>50です
>>51 rebind もそうですね
そもそも、クラステンプレートなり、構造体テンプレートを別のクラスで縛ることで得られるメリットってあるのかな?
普通に、そのクラスや構造体のインスタンスを生成して使うのが普通だし、譲歩して他のクラスから
そのテンプレートクラスなりが使いたかったとしても対等な関係で使えるはず
クラスが他のクラステンプレートや構造体テンプレートを所有するメリットについて、誰か説明してもらえませんか。
関数の引数がstd::stringとstd::wstringの違いで関数をオーバーロードさせる方法がわかりません。
std::wstring strmid (std::wstring, int, int) ;
std::string strmid (std::string, int, int) ;
を両用したいのです
ご教示お願いします
>>54 それでいけるでしょ
他の部分に問題があるのでは?
>>55 ヘッダーをincludeしてなかったので前方参照できなくて、再帰呼び出しで変換できないエラーになっていました。
ありがとうございます。
57 :
デフォルトの名無しさん:2011/08/25(木) 18:56:55.18
ファイルシステムにフックしてPC内データ全てのアクセスログを残そうと思うのですが、そういったことは可能でしょうか?
対象とするファイルシステムは?
60 :
デフォルトの名無しさん:2011/08/26(金) 11:42:13.68
ふっかつのじゅもん
>>57です。すいません、知識が浅く言葉足らずで。
Windows7/XP等でファイルシステムのシステムコールにフックして
「いつ誰がどのファイルを操作した」といったログを残したいのです。
これって無理なんですかね?
>>63 これはSetWindowsHookEx()を使ってフックする方法とはまた違うやり方なんですね
このクラスを使ったほうがいいんですかね・・・
linuxのルートみたいな存在感だ
WindowsNTのスレッドを強制終了するときに自動変数のデストラクタを呼ばせることはできない?
>>66 無理。
・NT関係ないだろ
・今時NTかよ
・C++やめてPerlにすればできるよ
68 :
デフォルトの名無しさん:2011/08/27(土) 05:34:23.37
わからないことが二つあります
using namespaceはヘッダファイルに書くのでしょうか?それともcppファイルに書くのでしょうか?
cppのどこかローカルなスコープに書くのが普通です
ヘッダに書いちゃうと忘れてまいます。
複数のcppファイルでプログラムを構成するとき、
あるcppファイルのグローバル変数は、そのcppのオブジェクト?の、クラスのプライベート変数のようなもの、
externでアクセスできるようになる
という理解はあってるんでしょうか?
>>72 あまり正確ではない
キーワードは「リンケージ」
cppで普通に変数や関数を定義すると、それは外部結合になる
外部結合ならば、extern int a;などと宣言することでそれにアクセスできる。
逆に
cppでstatic int a = 1;などと定義してある変数は内部結合になって、
それは宣言しようが、他のcppからはアクセスできない。
勿論ポインタが手に入ればアクセスできるが
関数の場合は宣言にexternつけなくても宣言になるけどな
>>73 半分くらい理解しました
精進します
むしろstaticの意味が理解できた気がします
クラスAの中でクラスBを生成してもOKですか?
これが包含ってやつですか?
>>75 C++は「クラス」を動的に生成することは出来ません
boostのasioでwebサイトを取得しています
このwebサイトはUTF-8です
コマンドライン引数で得た文字列をUTF-8にしてURLエンコードしてGETで渡したいのですがコマンドライン引数の入力の文字コードは何なのでしょうか?
できれば移植性の高いソースにしたいので入力の文字ーコードを割り出してUTF-8への変換を行いたいです
変換の方法や文字コードを調べる方法を教えてください
また、取得したwebサイトを
boost::asio::ip::tcp::iostream socket( "example.com", "http" );
socket << "GET ........" << std::flush;
std::string line;
std::ofstream fp( "test.txt" );
while( std::getline( socket, line ) ) {
fp << line << std::endl;
}
のようにしてファイルへの書き込みをしたのですが
コマンドプロンプトの設定をchcpコマンドを使わずにそのまますると文字化けし
chcpでUTF-8にすると文字化けせずに書き込みできるのですがどう関係しているのでしょうか
(コマンドプロンプトへの出力はフォントの関係でうまくいきませんでした)
最終的には
コマンドライン入力->UTF-8変換->web通信->処理->適切な文字コードに変換->標準出力
└─────UTF - 8─────┘
のように内部的にはUTF-8で処理したいです
stringやwstringなどいろいろありよくわからないです
長くなりましたがよろしくお願いします
osによるからなんともいえん
icuに丸投げ
UTF-8の文字列を保存するデータ型はchar*型(std::string)でいいのでしょうか
それだけでもいいので教えてください
w_char 型
$ echo $LANG
ja_JP.UTF-8
#include <stdio.h>
#include <string.h>
int main(void){
char *str="ほげほげ";
printf("%d\n",strlen(str));
return 0;
}
最初 ちょとびびるかもねw
>>76 すいません、オブジェクトAの中で、オブジェクトBを生成するのは可能ですか?
85 :
76:2011/09/02(金) 20:17:31.37
>>84 不可能なわけない。
struct A {
C c;
B *pb;
A() : c(100) { this->pb = new B(); }
};
BやCをAが所有するという考えの設計なら、包含とかコンポジションと呼んでよい
グローバル変数やグローバル関数は使うなっていう参考書は多いのですがグローバルなクラスを宣言することも推奨されないのでしょうか?
宣言しないと使えないだろ
使えないこともないよ
宣言?じゃなかったですかね
int hoge()
{
hoge hogege();
hogege.hogehoge();
}
だいたいこんな感じで関数の中で宣言して使ってるじゃないですか。
hoge hogege();
int hoge()
{
hogege.hogehoge();
}
こういうのはどうなのかなって。
hogeって何なんだろう、
>>89を見てると頭がおかしくなりそうだ
>>89 それってどっちでもコンパイルエラーでない?
あぁ、クラスの宣言には()いらなかったですね
・・・関数名と同じ名前にしたのはまずかったですね
上と下じゃまったく意味が違うだろ
>>86,89
用語は正しく使おうな。そこをあいまいにしてる人は物事を正しく理解できてないと思われてもしかたない。
で、君の言いたいことはクラスのインスタンス生成のことのようだが
グローバルなインスタンスは本質的にグローバル変数と同じものなので無闇に使うものじゃない
クラスをよく理解していない人のコードは、クラスを使用しない人のコードより汚いもんな
>>94 使わないほうがいいですか。
ありがとうございます
まだまだ勉強が足りませんでしたね。精進します
なんで関数の中でプロト宣言してるんすか。
ぐっぐっぐっ
ぐはぁっ
>>86 変数が組み込み型だろうとクラス型だろうと関係ない。
どうしても静的変数が必要な時のみ使用する。
>89
"グローバル"って、クラス内でスコープが有効って意味?
だったらそれは違う。
複数クラス間で共通に使用するインスタンスなら"グローバル"って呼ぶ。それは原則使用しない。
C言語とかだと、
・変数宣言が関数の中にある場合、スコープがブロック内で有効
・変数宣言が関数の外にある場合、スコープがソースファイル内で有効
って事で、
さらに複数ソース間でもスコープ有効をグローバルって言ってた
>"グローバル"って、クラス内でスコープが有効って意味?
グローバル変数はグローバル変数だよ。
関数外で外部リンケージの変数が定義されてるだろ。
>>89見てもわからないなら引っ込んでろ
> 関数外で外部リンケージの変数が定義されてるだろ。
いや、だから >89 に
class クラス名 {
public:
hoge hogege;
int hoge();
}
とかって書いて無いぢゃんw
publicでなくてクラス内で閉じてるなら、いわゆるグローバルと違うから問題無いって事だお。
>>86と
>>89と
>>92を読んで、ファイルスコープの変数でなく
クラスのメンバーを想像するなんて、Javaで頭がおかしくなったんじゃないのか
106 :
デフォルトの名無しさん:2011/09/10(土) 02:21:28.82
CreateFileW,CreateFileAにフックしてログを残すプログラムを作ったのですが、
エクスプローラ上でtxtを新規作成してもログに残りません。
テキストエディタでファイルを作成した場合はログに残ります。
エクスプローラはCreateFileを使用していないのでしょうか?
テストしたOSはWindows7です。
すれ違い。
108 :
デフォルトの名無しさん:2011/09/10(土) 18:23:36.34
コンパイル時定数を定義してる
110 :
デフォルトの名無しさん:2011/09/10(土) 18:34:39.32
>>109 すみません、難しくてわかりません。
出来ればもっと分かりやすく説明して頂けるとありがたいです。
112 :
デフォルトの名無しさん:2011/09/10(土) 18:39:16.72
>>111 ありがとうございます。
難しいですが大体わかりました。
char型のバッファをクリアするのにmemsetを使っています
memset(buf,0,sizeof(buf));
memset(buf,NULL,sizeof(buf));
どっちが一般的なのでしょうか?
ソースを他人に見せます。恥ずかしくないコーディングをしたいので教えてください
0がいいよNULLは基本的に無効なポインタを意味しててゼロの代わりではない
cならNULLの場合コンパイラに文句言われんじゃね
サンクス。0でいきます。
とあるクラス CHogeがあったとして、
CHogeのメンバ関数内での this というのは、
意味合いとしては、 CHoge*(CHoge型のポインタ) のような認識で合っていますか?
それと、 &this のような表記が意味するのは、
CHogeの実態へのアドレスを記憶する変数の領域が、thisという形で、他のメンバ変数のように存在しているということでしょうか?
クラスを利用していながら疑問に思っていた事なのですが、ご存じでしたらご回答お願いします。
>>117 その通り CHoge* だが、変数ではない。
*thisならよく見るけど&thisって初めて見た
&this->a
を
(&this)->a
だと思ってんだろね
121 :
117:2011/09/12(月) 13:26:44.22
>>118 納得しました。
>>119-120 &this 単体では利用できないのですね
というより、120さんのご指摘通りでした。
疑問が晴れました。どうもありがとうございました。
thisは参照にして欲しかったよね
thisが出来た時代に参照がなかったんじゃなかったっけ
そんな昔のことをいつまでもずるずると引きずってさー
前を向いて生きていこうよ。人間は忘れることで生きていけるんだよ
127 :
デフォルトの名無しさん:2011/09/12(月) 21:03:30.91
128 :
デフォルトの名無しさん:2011/09/13(火) 22:08:26.85
C++つかえるなら、Qt使え。
129 :
デフォルトの名無しさん:2011/09/14(水) 22:59:43.49
テンプレートの「typename T」のTがポインタであるか、
それ以外(intとか)ってどうやって判断したらいいのですか?
template < class T > struct is_ptr
{
static bool const value = false ;
} ;
template < class T > struct is_ptr< T * >
{
static bool const value = true ;
} ;
131 :
デフォルトの名無しさん:2011/09/14(水) 23:18:26.06
>>130 ありがとう。
ポインタのとき、charのポインタとか、intのポインタってのは判定できないのですかね?
132 :
デフォルトの名無しさん:2011/09/14(水) 23:24:54.10
やりたいことができました。
どうもありがとう。
template < class T , class U > struct is_same
{
static bool const value = false ;
} ;
template < class T > struct is_same< T , T >
{
static bool const value = true ;
} ;
template < class T > struct is_int_ptr
{
static bool const value = is_ptr< T >::value && ( is_same< T , int >::value || is_same< T , int const >::value ) ;
} ;
134 :
133:2011/09/14(水) 23:27:29.97
間違えてる。はずかしい///
135 :
デフォルトの名無しさん:2011/09/15(木) 01:12:11.46
>>133 やりたいことと違うけど参考になったよ。
ありがとう。
入門書よんでからテンプレートの本かったんですが、テンプレートって難しい…
template<typename T>struct rmp{typedef T type;};
template<typename T>struct rmp<T*>{typedef T type;};
template<typename T,typename U=typename rmp<T>::type>struct isp{enum{v=1};};
template<typename T>struct isp<T,T>{enum{v=0};};
template<typename T,int is_ptr=isp<T>::v>class my;
template<typename T>class my<T,1>class my{〜 //true
template<typename T>class my<T,0>class my{〜 //false
こういう事?
それ
template<typename T>class my{〜;
template<typename T>class my<T*>{〜;
でいいんじゃね?
C++のstringを学習中ですが、stringでは不可で、charなら出来る事ってあるんでしょうか?
スタックにおける
>>139 std::stringはスタックに置けないんですか?
>>138 C標準関数や多くのAPIはstd::stringを直接渡すようにできていない。
特に文字列を詰め込んでくれる関数の場合、一旦charのバッファを必要とする。
Cで書かれた文字列操作って引数stringでラップする時はどう書いてる?
毎回char配列でバッファ確保してコピーしてC関数通して逆コピーしてるけど
すごいもったいない気がしてstringを使う気が起きないんだけど
classについて教えてください
コンストラクタを使わないでクラスを使うことができますが
コンストラクタ使う・使わないのデメリット・メリットはあるのですか?
コンストラクタを使わないと静的領域に作られる?初期化を手動?
コンストラクタを使うとヒープ領域に作られる?
コンストラクタは使わなくても勝手に作られます
>>144 「初期化」と言うような処理がある状況でコンストラクタを使わなければ、
初期化を忘れたり2重に初期化してしまうなどの問題が起こる可能性が
高くなる。
領域の割り当ては関係ない。
領域割り当ては関係ないんですね了解
2重防ぐことでも使うようにします
ありがとう
>>143 バッファの連続性が保証されても、依然として&std::string[0]を
文字列の受け皿として使用するのは駄目だろう。
std::stringのオブジェクトとしての整合性が失われる。
>>148 サイズの範囲内なら文字列の中身が変化するだけなんだから問題ないだろう。
s[0] = 1, s[1] = 2, ... として書き込むのと変わらない。
整合性って、具体的に何のこと言ってるの?
例えばstrlen(&s[0])とs.size()が違う結果になる、とか。
Cの文字列APIは勝手にNUL止めしたりするでしょ。
>>150 strlen(&s[0]) と s.size() が常に同じになると思ってるなら、それはただの勘違いだ。
もちろん常に同じになるとは思っていなくて、同じにならなくなった状態が
不整合だと言ったんだよ。
まあ確かに今までも[]演算子でもC文字列としての長さは変えられるから、
変わらないと言えば変わらないが。
>>150 そんな「整合性」は提供されない。
s[0] = '\0' した瞬間に size() が 0 になったりはしない。
>>153 それは理解していて、故にそういう使い方をするのは駄目だと言っているの。
>>154 意味が分からないよ。
std::string が提供しない整合性が欲しいなら、その利用者がそのように使えばいいじゃないか。
それの何が駄目なの?
>>155 >std::string が提供しない整合性が欲しい
この時点で、std::stringを使うのは手段を間違ってるよね。
最初からcharバッファとして使うなら、オブジェクトとして文字列長を持っているstd::stringである必然性がなくて、vector<char>でいい。
std::stringを使うと混乱を招くと思わない?
>>156 それが嫌だってところから話が始まってんだよ。
>>141-142 読み直せ。
「整合」させたきゃ詰めた後に resize() すればいいだけだろ。
何の問題も無く std::string を使えるじゃないか。
結局のところ03の方でアロケータ−をいじる以外でこれ以上の効率化は無理ってことでFAですか?
void CFunc(char * zs);
void Func03(std::string & s)
{
std::vector<char> v;
v.reserve(s.size() + 1);
v.assign(s.begin(), s.end());
v.push_back('\0');
CFunc(&v[0]);
s.assign(&v[0]);
}
void Func0x(std::string & s)
{
CFunc(&s[0]);
s.resize(strlen(&s[0])); // 短くなった時のため
}
std::vector<char> v(s.c_str(), s.c_str() + s.size() + 1);
でいい
>>159 それだとstringが内部的に連続バッファじゃない場合に無駄が多くね?
c_strでゼロ終端作って、vectorにコピーだからコピー二回もしてる
流れはしらないがどうでも良いところに拘るなよ。
159を見る限りたいした事ではないんだろ。
>>158 サイズの受け渡しが無かったり入力と出力が別にできなかったり、
その CFunc() とかいう関数のインターフェースをどうにかしたいところ。
>>158 Func0xはs[s.size()]への書き込みが発生するからだめじゃないの
>>164 0xでは内部的にゼロ終端文字列で扱うことになったんじゃなかったっけ?
それともただ単に連続してることだけが保証されてるのかな?
s[s.size()]が0であることも連続していることも保証されるけど
shall not be modified だってさ
じゃあ非const操作は結局バッファ取らないとダメなのか…残念
>>167 いやいや、 shall not be modified なのは s[s.size()] で参照される値( '\0' への参照)だけだよ。
&s[0] から s.size() ぶんはただの char 配列と同じように使える。
つまり、短くなる分には普通に使える、と。
170 :
デフォルトの名無しさん:2011/09/18(日) 20:33:13.89
void func(int &f); ←func(i);のようなときに呼び出される。
void func(int f); ←func(123);のようなときに呼び出される。
このようにしたいのですが、コンパイルが通りません。
どうすればよいですか?
(func(int &f);をfunc(int *f);にすればとおりますが…)
希望の、「即値(リテラル)の場合は別動作」を実現するのは、たぶん不可能。
リテラルはconstであることを利用して、const&で振り分けることは可能だが
即値ではないconstな値を同様に処理してしまうという問題は出る。
それを振り分けて嬉しい時ってどんなとき
>>170 void func(int &f); ←func(i);のようなときに呼び出される。
void func(const int& f); ←func(123);のようなときに呼び出される。
>>173 ありがとうございます。
勉強になりました。
176 :
デフォルトの名無しさん:2011/09/18(日) 22:37:35.45
>>171 ありがとうございます。
奥が深いですね。
最近C++を始めたばかりで、いろいろ難しいです。
177 :
デフォルトの名無しさん:2011/09/19(月) 12:28:30.30
すみません。C++の関数定義の時の「:」について教えてください。
関数定義の際に
クラス名::関数名:親クラス(親クラスのメンバ変数),メンバ変数(0),メンバ変数(new でオブジェクト化){関数定義};
という↑一文があります。実際のソースコードは↓です。
WebView::WebView(QWidget* parent) : QWebView(parent) , m_progress(0) , m_page(new WebPage(this)) { // 関数定義 };
m_progress(0) と m_page(new WebPage(this)) の部分はWebViewクラスのメンバ変数なのですが、
この部分で初期化(インスタンス作成)してるみたいなんですが、そういうことはC++の文法上OKなんでしょうか?
どうも、この関数定義の際の「:」は意味が本を見てもあまり載っていないので、困っています。
178 :
177:2011/09/19(月) 12:30:05.82
ちょっと意味が分かりにくいです。
クラス名::関数名:親クラス(親クラスのメンバ変数),自分のメンバ変数(0),自分のメンバ変数(new でオブジェクト化){関数定義};
↑こうです。
初期化子リストでぐぐれ
ただコンストラクタ呼んでるだけだ
int* p(new int);
が合法なのと同じ
>>177 文法上OK
というかこれを使わないとデフォルトコンストラクタした直後に代入するという二度手間になって無駄なので積極的に使ったほうがいい
ただしここでthisを使うことはオススメしない
オブジェクトを構築するより先にthisを利用されるとバグを生む可能性がある
181 :
177:2011/09/19(月) 14:31:53.01
>>179 どうもありがとう。初期化子リストというのですね。名前を教えてもらえたので
グーグルで検索することができます。なにしろ、検索しようにも、コロン(:)では
中々ヒットしないので・・ ただ単純にコンストラクタを使ってるだけなんですね。
どうもありがとうございました。グーグルで更に検索して調べてみたいと思います。
>>180 どうもありがとう。
私はおっしゃるとおり、コンストラクタ内で代入するということをずっとしてきました。
こういうことの手間をはぶくために、この機能があるんですね。ひとつ教えてもらったので
これからはこの機能を使いたいとおもいます。thisは使わないようにすることをよく覚えておきたいと思います。
どうもありがとうございました。
ずっとこれはなんだろうとうやむやのままだったので、ようやくわかってすっきりしました。
どうもありがとうございました。
182 :
デフォルトの名無しさん:2011/09/19(月) 14:33:39.21
降っている雪をビルボードで1つ1つ表示する場合、雪1個につき1クラス用意して使い回したほうが良いですか?
それとも全部の雪をまとめて管理するクラスを1つ作ったほうが良いですか?
雪1個1個はキャラの動きや風、爆風などの影響を受けます。
画面上の雪は数百程度を予定しています。
描画回りは別問題として、負荷や速度の観点から、管理するスタイルはどちらが良いでしょうか?
誤爆か?
>>182 雪クラスと雪管理クラスを作って機能を分担
しかしそういうのは汎用のパーティクルクラスを作ったほうがよくないか
>>182 テクスチャとかの描画ステートが共通になるだろうから、そこをまとめた何かがあったほうが
安く上がると思うよ。
186 :
182:2011/09/22(木) 05:58:16.50
187 :
デフォルトの名無しさん:2011/09/22(木) 14:31:09.44
同じスレッドを2つ存在させても大丈夫なんでしょうか?
void thread_manp(void*){
int a;
while(1){
a++;
a--;
}
}
int main(){
pthread_t t1,t2;
pthread_create(&t1,null,thread_manp,null);
pthread_create(&t2,null,thread_manp,null);
while(1){
//関係ない処理
}
return 0;
}
こうした場合、2つのスレッドのメモリ領域などは別々に確保されたりして安全なのでしょうか?
OS:Linux(CentOS)
コンパイラ:gcc
問題ない
189 :
187:2011/09/22(木) 16:22:42.61
>>187 ローカル変数(スタック)は別に確保されるから全く問題ない。
グローバル変数の更新は対策が必要。参照する場合もタイミングに注意。
191 :
デフォルトの名無しさん:2011/09/23(金) 10:23:49.89
質問です。上図のポインタaが指し示しているクラスAの実体ってどこにあるのでしょうか?
クラスBはあくまでも(どこかしらに作成された?)クラスAの実体を指し示すポインタしか持ちませんよね?
くだらない質問で申し訳ありません
// A.h
#include <stdio.h>
#pragma once
class A
{
public:
A();
int getI();
private:
int i;
};
//B.h
#pragma once
#include "A.h"
class B
{
public:
B();
private:
A* a;
};
例を見る限りAをnewしている所がどこにもないので
Bのaは何も指してないかと
>>191 どこにあるか?そもそも実体を指しているのか?は、そのコードだけでは不明
ポインタがゴミかもしれない
Bのコンストラクタや他のメソッドで
new A してる
シングルトンかなんかで管理されているものを引き受けてる
かもしれない
//A.cpp
#include "A.h"
A::A()
{
i = 100;
}
int A::getI()
{
return i;
}
//B.cpp
#include "B.h"
B::B()
{
int i = a->getI();
}
いやいや、この場合は、何処を指してるか分からないが何処かを指している。
プロセスが持つメモリー範囲外−>エラー発生
プロセスが持つメモリー範囲内−>何かがおこるw、それはプログラムによるw
げ、リロードすれば良かった orz
197 :
デフォルトの名無しさん:2011/09/23(金) 11:05:04.58
1レス書き込むごとに「やられたでござる」とでてしまって、まともに書き込めない状態で申し訳ありません。先ほどの2連投の間隔があいたのもそういうことでした。忍法帖よくわからん・・・ もしもしに内容を送り、コピペしています。
それはおいときまして、この状態では、クラスBの中のメンバaはどこも指してない(厳密には未指定のどこかをさしている)状態で、
クラスBがクラスAのgetI()を使いたいだけ、という場合でも、
クラスBのコンストラクタで、
B::B()
{
a = new A();
int i = a->getI();
}
としてnewするか、クラスBのメンバをクラスAへのポインタをやめてクラスAの実体を持つことにするしかないわけですね。
ありがとうございました。
ちなみに、クラスの中で別のクラスのパブリックメソッドを使いたいだけのときは、ポインタメンバを持つのと、実体メンバを持つのとどちらが良いのでしょうか?好みですか?
getI() が Aのオブジェクト内に含まれている情報を使って動作するなら
どういう手段でやるにしろ 実体は欲しい
実体は不要で 実質namespace的な用途 って話なら変わってくるかもだが…
class A {
public:
int getI() { return 10; }
};
class A2 {
public:
static int getI() { return 10; }
};
B::B() { int i = A2::getI(); } と呼べるし、BにA2の実体や参照/ポインタを持つ必要がない
ハングル文字を出力しようとすると?になってしまいます
char* a = "?";
std::cout << a << std::endl;
どうすれば?
2ch書き込みも ? になってしまった・・・
? にはハングル文字が入ってると思ってください
ロケールをちゃんと設定しろ
確かにstaticパブリックメソッドにすれば、実体もポインタ/参照もなしで呼び出すことができますね
んーむむ、サンプルコードでの話の抽象化に失敗した気がするので、実際にやりたいことを白状しますと、DirectXの描画関数をクラスで整理したいのです。
描画の制御を別関数化、別クラス化しただけなので、引数、返り値のやりとりはないのですが、1つしかないデバイスの制御なので、実質グローバル関数的な立ち位置になってしまう、static関数はあまり使いたくなかったのです。
ならば、クラスGameMainでもfreindを使えばいい話なんですが、あまりfreindを多用する設計もいかがなものかと思い、呼び出し側のメンバに描画制御クラスを持たせました。(下記ソースコードの状態)
ここまではよかったのですが、ここで、「includeをなるべく使わず、ポインタメンバをもたせることによってincludeの数を減らせ」という文献にあたり、それにしたがってクラスの実体メンバからポインタメンバにしたところメソッドが呼び出せなくなってしまいました。
結局これは、「メンバ関数を使いたい場合にはポインタでもincludeが必要」という記述を見つけ、解決したのですが、
ならば、ポインタメンバを使ってもincludeを節約できないが、ポインタメンバと実体メンバどちらを使ったほうがよいのだろう?と思って質問したのが
>>191であり、>197でした。
長文になってしまい申し訳ないです
// DXBase.h
#pragma once
#pragma comment(lib, "d3d9")
#include <d3d9.h>
#include <d3dx9.h>
#include "winMain.h"
class DXBase
{
// 変数宣言
protected:
// DirectXオブジェクト
static LPDIRECT3D9 pD3D;
static LPDIRECT3DDEVICE9 pDevice;
private:
static D3DPRESENT_PARAMETERS d3dpp;
// 関数宣言
private:
// 初期化、終了処理 (winMain上で実行)
friend int APIENTRY _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int);
static bool Initialize(HWND _hWnd, bool isWindowed);
static void UnInitialize();
public:
// リセット
static void Reset();
};
// DXGraphics.h
#pragma once
#include "DXBase.h"
class DXGraphics :public DXBase
{
public:
DXGraphics(void);
virtual ~DXGraphics(void);
void Clear();
HRESULT BeginScene();
void EndScene();
void Present();
};
// GameMain.h
#pragma once
#include "DXGraphics.h"
class GameMain
{
// 変数宣言
private:
DXGraphics graphics;
// 関数宣言
public:
GameMain();
void MainLoop();
void Game();
};
// GameMain.cpp
void GameMain::MainLoop()
{
// バックバッファをクリア
graphics.Clear();
// 描画開始
if (SUCCEEDED(graphics.BeginScene()))
{
// GAME処理
Game();
// 描画終了
graphics.EndScene();
}
// バックバッファの内容を画面に表示
graphics.Present();
graphics.Clear();
}
>>202 > ここまではよかったのですが、ここで、「includeをなるべく使わず、ポインタメンバをもたせることによってincludeの数を減らせ」という文献にあたり、それにしたがってクラスの実体メンバからポインタメンバにしたところメソッドが呼び出せなくなってしまいました。
> 結局これは、「メンバ関数を使いたい場合にはポインタでもincludeが必要」という記述を見つけ、解決したのですが、
> ならば、ポインタメンバを使ってもincludeを節約できないが、ポインタメンバと実体メンバどちらを使ったほうがよいのだろう?と思って質問したのが
>>191であり、>197でした。
そういう点で言うなら、「前方宣言」を使えばいいよ。
具体的には、
>>191と
>>194のコードだと
>>191のコード
//B.h
#pragma once
// #include "A.h" 不要なのでコメントアウト
class A; // 前方宣言
class B
{
(以下略)
>>194のコード
#include "B.h"
#include "A.h" // 追加
(以下略)
> 1つしかないデバイスの制御なので
ならシングルトンクラスにすれば?
デバイスがひとつしか無いというのはハードの問題でそれをアプリケーションにもちこむべきではない
後でデバイスが増えたらどうするんだ
普通は増えたりしないし、万が一増えた場合は
最初から作り直した方が早いだろ
シングルトンで楽になるかどうかは知らんけど
>>206 ありがとうございます。ブックマークいれときます!
>>207 …なるほど!クラスの前方宣言とメンバの呼び出しの両立はできないと思っていましたが、実際にメンバを呼び出すcppファイル側でだけインクルードすれば実現できますね!目からうろこでした。ありがとうございます。
>>208 それは、少し考えました...が、今回はシングルトンなオブジェクトを継承させたいのです。
…おかしなことをいっていますが、うまくまとめられないので具体的な話をしますと、
>>203の
static LPDIRECT3D9 pD3D;
static LPDIRECT3DDEVICE9 pDevice;
上記2つ、これがアプリケーション上で「1つしかないデバイス」としたいものです。
そして、この2つをprotectedメンバにもつクラスDXBaseを、
>>204のようにDXGraphics, DXInput, DXCamera, DXLight....といった形で継承させ、
さらにDXGraphicsを継承させDX3DObject, DXText...といったクラスを作り、
それらのクラスでpD3D,pDeviceをライブラリ関数の引数として持たせたり、pD3D,pDeviceのメソッドを使ったりしたいのです。
シングルトンパターンに継承させるという概念?拡張?はないような気がしますし(不勉強なら申し訳ありません)、DXBase、DXGraphicsオブジェクトはアプリケーションに1つしか存在してほしくありませんが、
DX3DObject,DXTextなどは複数作成したかったりして、そこらへんがまだうまく消化しきれず、シングルトンパターンを適用するにいたっていません。
前述で継承させたい、と申しましたが、DXxxx系でのみpD3D,pDeviceにアクセスができ、
DXBase, DXGraphicsなどはシングルトンなオブジェクトに、DX3DObject,DXTextなどは複数オブジェクトを作成できる状態にできれば、継承にはこだわっていません。
また、DXGraphicsの子クラスにしたクラス郡も、意味的にそうしただけで、この形にはこだわってません。
当初の話とだいぶ離れてしまいました。申し訳ないです。
>>209 デバイスの周辺の話は、正直正確に把握できているか自信がないのですが、私が今回作ろうとしているのは「1つしかないデバイス」というよりは、正しくは「アプリケーション上ではひとつしか作りたくないデバイス」といったほうが良いのかもしれません。
サンプルソースでは本題でなかったので省略されていますが、
>>203のInitialize関数でデバイスの作成処理をしています。
それはシングルトンというよりモノステートパターンな気がする
>>213 モノステートパターン!いいキーワードを教えていただいた気がします。
グーグル先生のお世話になってきます。
お答えいただいた皆さん、ありがとうございました!
/*--- PCIOR0設定 PC8のLEDをを出力に設定 ---*/
PORT.PCIOR0.WORD |= 0x0100u;
質問です
上の文なんですけど
これって、PORT.PCIOR0.WORD と 0x0100u; を OR とって
その結果を PORT.PCIOR0.WORD に代入で良いのですよね?
0x0100u; の uって何ですか?
>0x0100u; の uって何ですか?
unsignedのu
浮動小数点の計算が環境によらずに同じ結果を返すようにしたい場合はどうすればいいんでしょうか?
例えばゲームをつくろうとしたときにプラットフォームごとに計算結果が違ったらシビアなゲームだと困りますよね
仮数部の中に余裕が出るように適用する式を考慮し変数も二進表現でなるべく小さくなる様に都度都度規則的な切り上げ捨てをする
floatだとあんまり機種依存しないような
>>221 俺の知る限りではハードウェアにもコンパイラにも依存する
IEEEではビット表現や四則演算の丸め方まで規定されてるはずだけど
たとえばx86では浮動小数点数を80bitのレジスタに格納して演算するので
メモリとの間のロードストアや使用する命令、順序だけで値が変わってくることに
なるし、MMXやSSEが使われればさらに変わってくる
よって、一言で言えば浮動小数点演算は非決定的であるということになる
(同じ入力から常に同じ結果が得られるとは限らない)
たとば離散コサイン変換は圧縮系のソフトウェア(JPEGやMP3)で常用されてるが、
それを浮動小数点演算で行っている場合、生成される結果はコンパイラや環境によって
実際に微妙に変わってくる
>>219 そのために厳密な有効桁数を設定してそこへの正規化を都度行なったり、
固定小数点実数を整備したり、パフォーマンスに影響しない範囲で工夫するしか。
224 :
デフォルトの名無しさん:2011/09/25(日) 02:52:09.50
質問です。Singletonパターンを以下のようなコードで実装しました。
これを拡張して、コンストラクタに引数を投げて初期化したいのですが、どのような形で実現するのが一般的でしょうか。
Instance関数に毎回初期化用の引数を持たせるのは現実的じゃありませんし...
それともSingletonパターンで引数ありのコンストラクタを使用しようとするのが無謀なのでしょうか。
http://codepad.org/Dbpg8Xp0
代入でダメなら初期化を義務付けたら?
A* A::Instance()
{
if (!_instance) { throw; }
return _instance;
}
A* A::Initialize(...)
{
if(_initialized) { throw; }
Locker lock(m);
if(_initialized){
_instance = new A(...);
_initialized = true;
}
}
Singletonなんだし決めうちでいいとは思うけど。
>>225 ありがとうございます。
>Locker lock(m);
この行みなれないんですが、軽く検索して出てきた、マルチスレッドプログラミングで排他処理をしている何か、という理解で大丈夫だったでしょうか?
227 :
デフォルトの名無しさん:2011/09/25(日) 14:08:39.04
初心者姦ゲイ 姦狂依存OK
228 :
226:2011/09/25(日) 14:16:27.18
>>225 C++だとdouble-checked lockingの問題は起きないの?
なんとなく”大丈夫そうに見える”コードではあるけど
それにシングルスレッドならそのロックは無駄だし
複数スレッドからInitializeされない保障があればそのロックは無駄じゃね?
このコードじゃ内側のifの中は実行されることがないからある意味大丈夫だな
そもそも初期化を義務付ける時点でアレだろ
>>224 Singleton はやめとけ。無理がでてきたんなら、ちょうどやめどきだ。
そうそう、初期化を義務付けてる時点でガチホモのゲイ
234 :
デフォルトの名無しさん:2011/09/25(日) 17:22:29.79
苦Cって評判どうなの?
ファンネルミサイル搭載なのでアンチビームを搭載しているMSに強い
> コンストラクタに引数を投げて初期化したい
まぁシングルトンでなければならない理由が分からんのだが
"シングルトンクラス内部で保持するインスタンス生成"メソッドを外部から実行出来る用意して、そいつで初期化すればいいんじゃねの?
もちろん"インスタンス生成"メソッドを誰もが何度も実行しちゃうのどうよ?とかいろいろ考慮必要だけどね
iteratorがポインタかイテレータの型でstd::なんちゃら<iterator>でそのポインタかイテレータの持っている値の型を返すメタ関数があったと思うのですがわすれてしまいました
教えてもらえないでしょうか
iterator_traits
たとえばレジストリから読んだ情報をもとにインスタンス作りたいとかかな
この例だと、シングルトンが自分で情報を取りに行くようにしたほうが楽だとは思う
8、16、32Bitの符号なし整数の型を得るメタ関数ってどうやって書きますか?
>>241 こんな感じ?
template<int N> struct uint {};
template<> struct uint<8> { typedef uint8_t type; };
>>242 すいません言い忘れました
stdintを使わない場合のはなしです
>>242 すいません言い忘れました
パソコンを使わない場合のはなしです
DirectShowの使い方について詳しく解説してる本、サイトってないでしょうか?
メディアデバイスへのアクセスをしたく思っているのですが、
調べ方が悪いこともあり、みつからずにいるのですが、、、
>>243 まず stdint と同等の typedef を用意して(以下略
あぁ俺それよくやっちゃうわ
>>243 無理じゃね。
uintN_t型以外で確実にNビットであるunsigned型なんかないだろ。Nビット以上であることは保証されてる型はあるけど。
>>229 Javaにおける、その問題点は
A *p = new A(); が、
Javaにおいては
A *p = ::operator new(sizeof(A)); //メモリだけを確保
new (p) A(); //配置newによるコンストラクタの呼び出し
という形で行われることを許容していることが原因だったはず。
C/C++においては、通常は=の右辺の演算が行われてから代入されるが
規格において、=の前後にシーケンスポイントは無かったと思うので(詳しい規格は知らない)
コンパイラがそのようなコードを出力することも、絶対無いとは言い切れない、と思う。
が、普通は、最適化OFFであっても、そのような無駄なコードはまずあり得ないはず。
でも、俺がそういうコードを吐くコンパイラを見たことがない、というだけで
厳密なことは知らない。
ただ、C++においてはローカルなstatic変数の初期化の方を問題視する場合も多いので
重視されていないだけかもしれない。
確実な方法は無いよね。CHAR_BITが8以外もありえるし。
#include <iostream>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/eval_if.hpp>
using namespace boost::mpl;
template <typename Vec, int NBits>
struct uint_impl {
static const bool Hit = (sizeof(typename front<Vec>::type) >= (NBits+7)/8);
typedef typename eval_if_c<Hit, front<Vec>, uint_impl<typename pop_front<Vec>::type, NBits> >::type type;
};
template <int NBits>
struct UInt {
typedef vector<unsigned char, unsigned short, unsigned, unsigned long, unsigned long long> Vec;
typedef typename uint_impl<Vec, NBits>::type type;
};
int main() {
UInt<8>::type a = 0;
std::cout << sizeof(UInt<8>::type) << std::endl;
std::cout << sizeof(UInt<16>::type) << std::endl;
std::cout << sizeof(UInt<32>::type) << std::endl;
std::cout << sizeof(UInt<64>::type) << std::endl;
}
boost使うならstdint.hppでよくね?
numeric_limits<T>::digits を使えば何とかなるかもね。
>>252 ほぼドンピシャのがあるね。あとは
>>250みたいなのと組み合わせればいける。
もちろんboost使わずに泥臭く書くのもありだし、C++11ならvariadic templatesを使えば簡単に書けそう。
そもそもC++11ならstdintがあったか・・
VC++2010でプログラムを書いているのですが・・・
class hoge
{
private:
deque<int> DEQ
}
void hoge::Push_num(int a)
{
DEQ.push_back(a);
}
これだけで何故か実行するとエラーが出て、次のような場所に飛ばされます
inline void _Container_base12::_Orphan_all()
{ // orphan all iterators
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Myproxy != 0)
{ // proxy allocated, drain it
_Lockit _Lock(_LOCK_DEBUG);
for (_Iterator_base12 **_Pnext = &_Myproxy->_Myfirstiter;
*_Pnext != 0; *_Pnext = (*_Pnext)->_Mynextiter)
(*_Pnext)->_Myproxy = 0;
_Myproxy->_Myfirstiter = 0;
}
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */
}
何が悪いのか全く検討もつかないのですが・・・
セミコロンが無かったり関数の定義が無かったりするけど
中途半端に書き写したりしないで全部コピペしたら?
>>255 class hoge
{
private:
deque<int> DEQ
public:
void Push_num(int a)
{
DEQ.push_back(a);
}
};
または
class hoge
{
private:
deque<int> DEQ
public:
void Push_num(int a);
};
void hoge::Push_num(int a)
{
DEQ.push_back(a);
}
×検討
○見当
259 :
255:2011/09/26(月) 18:56:17.47
すいませんちょっと急用ではずしてました
コードは257さんの書いてくれた上の方です(最も両方試して同じだったのですが・・・)
それでやっていることは
class Main
{
private:
hoge h;
public:
void mainloop();
}
void Main::mainloop()
{
int a=3;
h.Push_num(a);
}
これだけなのです。単に呼び出して入れるだけで上記のエラーが出ます
実際には他にも関数などがありますがエラーが出る関数でやっていることはこれだけです
DEQに入っている個数は関係ないようで空でもなります
>>259 classの最後にセミコロンが無いんだけど
書き写しせずにコピペしろって
>>260 関係ないものが多量にあるのですが・・・
>>261 関係あるかどうかはこっちが判断するんだよ
エラーはその行番号で起きているんじゃない。
その行番号以外の箇所で起きたエラーがその行番号で顕在化するだけだ。
だから、再現する最低限のソースを全て貼れ。
>>261 元の環境を壊さないためにもまず最初にプロジェクト全体をコピーしてそっちで作業するようにして、
不要と思う場所を全部コメントアウトする。
それでも同じエラーが出る場合、コメントアウトした場所を削除してここに貼り付ける。
じゃあ500行ぐらいありますが・・・
と思ったら解決してしまいました・・・お騒がせしてすいません
class hoge
{
private:
int error[5];
deque<int> DEQ
public:
};
error[5]=num;
これが原因でメモリを突き抜けてたみたいです・・・
クラスでエラーが出たときは別の変数も見ないとダメですね。
自分が不要だと思っていた所が全然不要じゃなかったことが見にしみました
「身に染みる」な
変換ソフト変えたほうがいいんじゃね?w
まず「問題が再現する最低限のコード」を貼るのが基本です
おおよそ その絞り込みの過程で自己解決に至る罠だな
初心者丸出しで申し訳ないですが、以下のように、
可変長引数に対して動的にメモリを割り当てたいのですが、
左辺にはva_argマクロをおけず、エラーとなります。
void func(int dummy,...)
{
va_list args;
va_start(args,dummy);
va_arg(args,double*)=malloc(sizeof(double)*N);
va_end(args);
}
このような場合に、何かうまい解決策はないものでしょうか。
なお、OSはUbuntuで、コンパイラはインテル C++ コンパイラの非商用版です。
よろしくお願いいたします。
>>269 一度va_argの値を変数に代入すればいいでしょ
void func(int N, ...)
{
va_list args;
double **p;
va_start(args, N);
p = va_arg(args, double **);
*p = (double *)malloc(sizeof(double) * N);
va_end(args);
}
int main(void)
{
double *p;
func(10, &p);
p[0] = 1.0;
printf("%f\n", p[0]);
free(p);
return 0;
}
>>270 早速の返信ありがとうございます。
一回変数をかませるということに考えが至らなかった・・・orz
勉強になりました。ありがとうございました。
可変長引数を使った汎用性のある関数を作ってしまうのは誰しも通る道
ioctl()ですねわかります
274 :
269:2011/09/27(火) 21:37:11.05
再度失礼いたします。
先日いただいた指摘を元にコードを組んでみたのですが、
どうにもsegmentation faultが取り除けず、困っております。
もしよろしければ、再度見ていただけないでしょうか。
以下がコードです。
http://codepad.org/O5ITfhND http://codepad.org/BhDlvQRc 上が問題ないコード、下が問題のあるコードです。
new_memory、およびdelete_memoryは単独では
問題なく動きます。setArrayおよびfreeArrayも、
可変引数がひとつの場合はちゃんと動くのですが、
下のように二つ以上になるとsegmentation faultと
なってしまいます。どうやら可変長引数を解析する段階で、
一つ目の変数しかメモリを確保していないようです。
275 :
デフォルトの名無しさん:2011/09/27(火) 21:56:36.72
初心者姦ゲイ 姦狂依存OK
va_argを再度呼ばないと次の引数にアクセスできないぞ
というかC++でそういうのやめろよ
>>274 そもそも、setArrayは、何故に可変引数を受け取る形にしてるわけ?
まあCなら、&でアドレス渡しにすると型とかがどうなるのかよくわからない、
というのも理解できなくはないけど
C++なのだから、参照渡しにすれば(見た目)同じdouble**型を扱うだけで済むでしょ。
可変引数のおべんきょ、ってわけでも無さそうだし。
C++0xのbindに関する質問です。
下記の実験コードで、VC2008で動作していたものが
VC2010でstd::bindにエラーが出てコンパイルが通らなくなりました。
#include <functional>
#include <algorithm>
#include <vector>
#include <list>
namespace std { using namespace std::tr1; }
using namespace std::tr1::placeholders;
struct STRUCT {
int a;
};
typedef std::vector<STRUCT> VStruct;
typedef std::list<VStruct> LVStruct;
static LVStruct lvs;
int main()
{
const STRUCT str = {0, 0, 0};
std::for_each(lvs.begin(), lvs.end(), std::tr1::bind(&VStruct::push_back, _1, str));
}
namespaceの部分からtr1を取り除いてcygwin版g++で試したところコンパイルが通らなかったので、
もともとNGだったようなのですが、bindをどう修正すればよいのか教えて頂けないでしょうか。
※エラーコードは長いので、先頭の方を抜粋して次レスに書きます。
std::tr1::bind(&VStruct::push_back, &lvs, _1, str));
282 :
280:2011/09/27(火) 23:01:25.47
上記のVC2010コンパイル時エラーです
1>d:\usr\home\var\dev\testfunc\main.cpp(27): error C2780: 'std::tr1::_Bind<_Rx,_Rx,std::tr1::_Bind10<std::tr1::_
Callable_pmf<_Rx(__fastcall _Farg0::* const )(_Farg1,_Farg2,_Farg3,_Farg4,_Farg5,_Farg6,_Farg7,_Farg8,_Farg9)
volatile const,_Farg0>,_Arg0,_Arg1,_Arg2,_Arg3,_Arg4,_Arg5,_Arg6,_Arg7,_Arg8,_Arg9>> std::tr1::bind(_Rx (__fastc
all _Farg0::* const )(_Farg1,_Farg2,_Farg3,_Farg4,_Farg5,_Farg6,_Farg7,_Farg8,_Farg9) volatile const,_Arg0,_Arg1
,_Arg2,_Arg3,_Arg4,_Arg5,_Arg6,_Arg7,_Arg8,_Arg9)' : 11 引数が必要です - 3 が設定されます。
1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\xxbind1(1026) : 'std::tr1::bind' の宣言を確認してください。
※後は延々と同じエラーが100個ほど出てからコンパイラが
error C1003: プログラム内のエラーが 100 個を超えました。コンパイルは中断されます。
といってコンパイルを断念します。
283 :
281:2011/09/27(火) 23:05:27.16
ちょっと間違えた
というかVStructのインスタンスはどこにあるの?
284 :
280:2011/09/27(火) 23:11:13.17
>>281 回答ありがとうございます。
VStructのインスタンスは実際のコードだとfor_eachを呼び出す前に
LVStructにpush_backでコピーしています。
もしかして
std::for_each(lvs.begin(), lvs.end(), [str](VStruct& vec) {
vec.push_back(str[0]);
vec.push_back(str[1]);
vec.push_back(str[2]);
});
こういうことがやりたかったのかな?
286 :
280:2011/09/27(火) 23:32:52.14
>>285 str[1]1、str[2]は不要ですが、概ねそのようなものです。
※というか、この場合str[1]、str[2]って何を指すのでしょうか?
意図としては
lvsに複数のvectorが登録済みで、外部から与えられた値strを
全てのvectorにコピーするための処理です。
うまく表示されるかわかりませんが
lvs---+--vec[0] <= str
+--vec[1] <= str
+--vec[2] <= str
上記のようなイメージです。
>>286 > const STRUCT str = {0, 0, 0};
これが配列に見えただけ
bindでメンバ関数呼び出すには第二引数がインスタンスへのポインタじゃないとダメ
288 :
280:2011/09/28(水) 00:16:12.93
>>287 回答ありがとうございます。
第二引数が _1の方かstrの方かわからなかったので
typedef std::vector<STRUCT*> VStruct;
typedef std::list<VStruct*> LVStruct;
上記両方試してみましたがどちらにしろVC2010、g++どちらもエラー内容は変わりませんでした。
>>288 _1の方
インスタンスへのポインタっていうのはそういう意味じゃない
VStruct v;
std::tr1::bind(&VStruct::push_back, &v, str)(); // これはOK
std::tr1::bind(&VStruct::push_back, v, str)(); // これはダメ
まあlambda使えばいいじゃん、というのは置いといて
std::bind<void (VStruct::*)(const STRUCT &)>(&VStruct::push_back, std::placeholders::_1, str)
push_backにmove用のpush_backが追加でオーバーロードされて一意に決定できなくなったから
呼び出すべき関数の型を明示する必要がある。
291 :
280:2011/09/28(水) 00:53:34.75
>>290 moveセマンティクス対応でしたっけ。
記載していただいた対応をしてみたらエラーメッセージが変わりました。
このあたりに原因がありそうですね。
1> include\xxcallobj(13): error C2064: 2 引数を取り込む関数には評価されません。
1> include\xxbind1(292) : コンパイルされたクラスの テンプレート のインスタンス化
'_Ret std::tr1::_Callable_obj<_Ty,_Indirect>::_ApplyX<_Ret,std::vector<STRUCT>&,_Arg&>(_Arg0,_Arg1)' の参照を確認してください
1> with
1> [
1> _Ret=_Rx,
1> _Ty=void (__thiscall std::vector<STRUCT>::* )(const STRUCT &),
1> _Indirect=false,
1> _Arg=STRUCT,
1> _Arg0=std::vector<STRUCT> &,
1> _Arg1=STRUCT &
1> ]
それじゃ返却値型も明示は?
std::bind<void, void (VStruct::*)(const STRUCT &)>(&VStruct::push_back, std::placeholders::_1, str)
293 :
デフォルトの名無しさん:2011/09/28(水) 04:12:41.01
遅くなりましたが、皆様ご指摘ありがとうございます.
そもそもsetArrayのような関数を定義したのは、
同じサイズの2次元配列を異なる名前で大量に
(50個以上)確保する必要があり、それを
コード上にベタ打ちしたく無かったからです.
すなわち、可変長引数の部分にはdouble**型の引数が
(そしてそれのみ)大量に存在し、そのそれぞれについて
2次元配列を確保したい、と言うことです.
>>275 va_startからva_endまでが勝手にループになっていると
勘違いしていました.ありがとうございます.
C++ではこのような書き方は推奨されないのでしょうか.
>>276 参照渡しというものがあるのですか.勉強します.
>>277 まさにそのようなかんじです。第一引数に可変引数の
個数を書いておけばよかったのですね.このコードは、
それぞれの配列のサイズを変える場合に拡張してある、
という理解でよいでしょうか.
>>279 可変引数には何か問題があるのでしょうか.
std::bind(std::mem_fn((void (VStruct::*)(const STRUCT &))&VStruct::push_back), _1, str)
ラムダか自分でファンクタ書いたほうがいいって
295 :
269:2011/09/28(水) 04:50:42.36
296 :
280:2011/09/28(水) 07:55:41.17
>>292 >>294 ありがとうございます。どちらのコードもVC2010でコンパイルが通る事が確認できました。
ラムダかファンクタ書いた方が良いのはその通りですね。
実際にVC++2010に移植する際にはラムダ式に書き換えようと思います。
(今回は移植可能かの調査だったので、元コードをあまり変えないで解決しようと考えていました)
※一応試してみたg++ 4.3.4 -std=c++0xでは、やはりエラーは治りませんでした。
>>292はエラー変化なし、
>>294は「address of overloaded function with no contextual type information」といった体です。
g++はVC++より型解決が厳しいのでしょうね。(後に出たエラーはよくわかりませんでしたが)
g++はやたらコンパイルエラーにするだろ。
GCC4.5.1はどっちも通るな
VC++2010のフリーのやつでWin32APIプログラムを勉強しはじめたんだが、
クラスファイルとソースファイルのわけかたがよくわからないでつ。
一つのソースファイルにクラスを複数書くと相互参照とかができなくて不便なんですが
共通のヘッダファイルみたいなのを作ってその中にクラスを入れたりすればいいの?
#include "共通ヘッダ.h"
int WINAPI WinMain(HINSTANCE hi, HINSTANCE hi2, LPSTR pstr, int wwwwwww)
{
クラスA* ca = new クラスA();
クラスB* cb = new クラスB();
ca->数値 = 0;
cb->数値 = 8;
ca->数値 = cb->数値;
ca->メッセージテスト();
cb->メッセージテスト();
delete(cb);
delete(ca);
return 0;
}
関数はヘッダファイルなしでもexternを描けば他のCPPファイルの関数やら変数やらを扱えるけど
クラスの場合はクラス名だけexternしてもだめっぽくてクラスの宣言と実体を分けて記述しなきゃいかんの?
↓こんなかんじでいいのかな?
クラスA.h
#ifndef _インクルードガード_クラスA_
#define _インクルードガード_クラスA_
#include "共通ヘッダ.h"
class クラスA
{
public: int 数値;
public: クラスA();
public: ~クラスA();
public: void メッセージテスト();
};
#endif//_インクルードガード_クラスA_
CPPはこんな感じで
#include "共通ヘッダ.h"
クラスA::クラスA()
{
MessageBox(NULL,"クラスAのコンストラクタ","",MB_OK);
}
クラスA::~クラスA()
{
MessageBox(NULL,"クラスAのデストラクタ","",MB_OK);
}
void クラスA::メッセージテスト()
{
MessageBox(NULL,"クラスAのメッセージテスト","",MB_OK);
}
で、こんな感じで共通の?ヘッダファイルを作ればとりあえず期待通りに動くんだけど
作法的にっていうかデザイン的にっていうかこんな感じでいいんでしょうか?
#ifndef _インクルードガード_共通ヘッダ_
#define _インクルードガード_共通ヘッダ_
#include <windows.h>
#include "クラスA.h"
#include "クラスB.h"
#endif//_インクルードガード_共通ヘッダ_
インクルードとかインクルードガードとか
みんなよく理解できるよね。慣れれば楽勝なの?
JAVA使ってたのでプロトタイプ宣言とかヘッダファイルとか
わけわからんです。
おまえらよくわかるね。すごすぎ。
templateが入ったら死ねるな
コンパイラが(条件付きで)コピペしてるだけ include
2回以上同じクラスの宣言しちゃまずいから コピペ抑制の為にガードしてるん
テンプレートを使わないとして
共通ヘッダ.hを全てのファイルでインクルードしまくるってのは
コンパイルが遅くなる以外でなにかまずかったりするの?
特に問題ないの?
テンプレートを使うともっと複雑になるのでつね。
>>303 そのやり方は無駄なインクルードが多くなるしいつか相互インクルードにぶち当たるからやめたほうがいいな
クラスはexternじゃなくて前方宣言する
複雑とかそういう問題よりほとんどのコンパイラはexport templateをサポートしてないから
標準のnewやmallocはスレッドセーフですか?
>>308 前方宣言というのはプロトタイプ宣言みたいなやつ?
こんな感じでいいのでせうか?
#include <windows.h>
class クラスA;
class クラスB;
#include "クラスA.h"
#include "クラスB.h"
int WINAPI WinMain(HINSTANCE hi, HINSTANCE hi2, LPSTR pstr, int wwwwwww)
{
クラスA* ca = new クラスA();
クラスB* cb = new クラスB();
ca->メッセージテスト();
delete(cb);
delete(ca);
return 0;
}
しかしこれだとクラスのヘッダファイルごとに#include <windows.h>しないとだめでせうよね?
プリコンパイルヘッダが大抵のコンパイラでサポートされてるから問題ないだろ
>>311 あー前方宣言の話をしたのがまずかったかな。
とりあえず共通ヘッダーは相互インクルードっていうのが起きる可能性があるからそれに注意する
前方宣言は相互インクルードを防ぐ手段の1つ
前方宣言は#include "クラスA.h"をインクルードしたらエラーが起きるけどクラスAを使用したい時に使う
だからそのWinMainのやつでは普通に#include "クラスA.h"できるからいらない
>>311 クラスAとクラスBが相互参照しているなら、
class クラスA;
はクラスB..hに、
class クラスB;
はクラスA.hに記述されてるはずでは?
ヘッダファイルは「それをインクルードする時にXX.hも一緒にしなければならない」
というような前提条件を作らないのが基本。
もし、まっさらのcppに
#include "クラスA.h"
だけ書いてコンパイルしてwindows.hが必要だってエラーが出るならそれはクラスA.hに含めるべき。
その上で、ヘッダファイルがヘッダファイルをインクルードする回数を極力減らすようにする。
相互インクルードさえ気をつければ とりあえずこれでいいってことでOKでつか?
>>314 相互参照の話は共通ヘッダーを使うと相互参照が起きる可能性があるよって話だけで
別にAとBが相互参照してるわけじゃない・・・と思う
>>315 とりあえず、な。でも使わないほうがいいとは言っておく
>>300で
> 相互参照とかができなくて不便
とか書いてたから、既にしてる/これからする可能性がある、のかと思って書いた。
してるなら設計まずいし、してないならそれに越したことないね。
ありがとうございまつた。
実際相互参照できたら便利じゃん と思っていたけど
できるかどうか検証してみたらやらないほうがいいのがよくわかりまつた
今回は長々と質問に答えていただきましてありがとうございまつた
OOPの原則だしな。
fstreamであるファイルをオープンしたときに、別のスレッドやプロセスによる後続のファイルオープンを制御することってできますか?
最初のファイルオープンが読 → 後続は読のみ許可
最初のファイルオープンが書 → 後続はオープン禁止
という感じで
fstreamだとできるか知らないけど、
Windowsなら、CreateFileで共有モードを適切に設定すればできそう
>>322 前者: chmod -w
後者: chmod -rw
固定小数点(整数の組みで)ならテンプレートつかってコンパイル時計算できるように思えるんだけど
そういうライブラリってすでにどこかにないっすか?
inline void Func( double const & d )
{
// dは使われない
}
int main( void )
{
double x , y , z;
Func( x * y * z ) ;
return 0 ;
}
こういうコードはメジャーなコンパイラでは最適化されてx*y*zの計算はスキップされたりする?
なわけねーだろ
VC++ はrelease時、省略される
x,y,zに初期値入ってないよ
最適化オプション付ければ省略されるんじゃね
bcc32(5.82 オプション -G)、gcc(4.6.1 オプション -O2)で省略された
まずFuncが最適化で実際にインライン展開されるかどうかが鍵だな
場合によっては使われないか
何があっても使われないかにも寄るな → だったら(double const&)にしとけよと
boost::shared_vectorってなんでないの?
ptr_vectorじゃダメなの?
全然違うじゃん
vector<shared_ptr<T>>じゃダメなの?
>>の間にスペースないからダメ
と思ってたら最近のコンパイラはエラーにならないのね
それってどんな場面で役立つの?
C++11ではOKになったね
shared_arrayの可変長版みたいな意味ね。ptr_vectorは用途が違う
>>340 shared_ptr<vector<T> >
格納要素とポインタ要素等で持つ一次参照先への変更一切を遮断するアンチオンラインvector欲しいかも
ファイル関連をラップしてるのですが
返す整数値が0以上ならファイルハンドルで負ならエラーという仕様です。
現状intをキーとしたファイル情報のmapを使って要素が空なら0を、
空でないなら最終要素のキーに1を足した値をキーに使ってファイルハンドルとして返しています。
あまりよい方法に思えないのですが、なにかよい方法はないでしょうか?
ごめん
何言ってんだかわかんない
345 :
343:2011/10/11(火) 21:07:06.74
ごめん
何したいんだかわかんない
>>343 なぜFILE*を敢えてそういう形でラップしたいのかは分からんけど
少なくとも実装がスレッドセーフにはなっていないな
それと、map<>でもいいけど、やや富豪的というか……
intがキーで0から採番していくんなら、配列かvector<>でよくね
別途フリーリスト管理をしないなら、空きスロットを探すときに
下から舐めないといけないから、open相当の処理は多少遅くなるが
物凄く大量のファイルを開くわけでもないだろうから(どうせ制限がある)
リニアに舐めたところで全然大した話じゃないし、それ以降のアクセスはO(1)で済む
メモリの無駄も少ないだろう
>>345 そんなラップならしない方がマシだと思う
>>347 eraseしたら乙るね
>>348 何がしたいのかも聞かずに
頭ごなしに否定するのはどーかと思う
いや、>346で聞いたつもりなんだけど
こういうのはどういう使われ方をされるかから考えて決めるもんだよね。
>>343は内部の処理から決めようとしてるからうまくいかない。
後は気になってるのがg_IoList
グローバル変数のつもりなら改めて否定させてもらうよ。
>>349 配列やvector<>を使うなら、close()したら、この場合は単にdeleteして
ヌルポインタをかわりに入れるような実装を想定していたよ
開きスロットとかフリーリスト管理とかいうのは、そういう意味
352 :
343:2011/10/11(火) 22:15:34.63
システムが開けるファイル数に制限があり、最大でも10個までしか開けません。
それを擬似的に可能にしようとしてあのようなコードになりました。
mapかvectorかはどちらがよいのかわからずmapを使ったのと、
スレッドセーフ云々は見づらくなるので省きました。
>システムが開けるファイル数に制限があり、最大でも10個までしか開けません。
>それを擬似的に可能にしようとしてあのようなコードになりました。
ちょっと言っている意味が分からない
システムってのはOSや処理系のことじゃなくて、自分が作ろうとしている
シロモノのことか?
その自分が作ろうとしているものに、ファイルを最大10個しか開けないように
しなければならない、という謎の要求仕様があるので、ああいうものを作った
ということで合ってる?
その仕様なら配列で十分、mapもvectorも要らん
システム的に制限があるのはわかったけど、
そういうのは事前に書いておく方がいいよ。
他にもメモリが超少ないとかあったら早めに書いてね。
(組み込み系の人かな?)
> 擬似的に可能にしようとしてあのようなコードになりました。
話を聞いた後でコードを見直してもそんな事情なんてさっぱりわからんw
どういう方針で可能にするつもり?
例えば、10個既に開いてる時に更に要求が来たらどう対処するの?
>>350 346=348なんてのは書いた本人にしか分からん
>>351 後半読んでなかったわ、なるほどね
>>352 うん
人にはいろいろ悩みがあるよね
で、何がしたくて悩んでるの?
おっと、IDが出てなかったんだっけ。こりゃ失敬。
>346=>348=>350=>355です。
なんとなく>343の事情が見えてきたな。
状況を説明すると仕事だってバレるから必要な情報ですら小出しにしてたんでしょ。
358 :
343:2011/10/11(火) 22:58:51.08
システムはOSのことで、メモリも超少ないです。(某ゲーム機です)
小出しですみません。
説明大変なので全部上げます。
mutex関連は説明長くなるので省きました。
http://ideone.com/idaD5 あと仕事じゃなくてただの学生の趣味です。
11個以上開くときは実際にはオープンしないで読み書きするときに開きなおしたりするんじゃないか?
>>358 IoCtx*をかえせばいいんじゃないの?
>>358 C>C++がすんなりいかない人は
間にJavaやC#を挟むといいよ
358でわかるって
363 :
357:2011/10/11(火) 23:38:37.76
>>358 better Cで全部行くつもりなのね。
この使いかたならグローバルも仕方ないか…
mapやlist使うの止めて自前のリングバッファにすればずっと簡潔・高速になると思うよ。
正直無駄なことばっかやってるようにみえる。
なんだ、システム側の制限で開けないって話だったのか?
なら、なんで自分でわざわざ管理するのかやっぱり分からんな……
自分で管理してもシステムの制限は越えられないのんと違う?
だから、システムの制限よりなんらかの理由で減らしたいから管理してるのかと
思ってた
それとも、ファイルうっかり開きすぎてもEMFILE(Too many open files)が
帰ってこないようなシステムなんか?
365 :
343:2011/10/11(火) 23:50:06.26
>>360 openを置き換えれるようにint型で管理したいんです。
>>363 無理にSTL使う必要はないんですね。
C++は多機能すぎて選ぶのが難しいです。
おとなしく自前にします。
>>364 読み書きのたびに開いたり閉じたりしています。
そのままだとさすがに遅いので若干工夫したつもりですが…。
>読み書きのたびに開いたり閉じたりしています。
なるほど、そこまで聞いてやっと意図がわかった
367 :
357:2011/10/12(水) 00:00:03.78
そういや数年前、似たような制限付きの仕事やったな。
書いたコードも
>>358よりは上手いつもりだが、大筋似たようなコードになった。
>>365 返すときにintにキャストすればいい
負ならエラーっていう仕様も満たしたければ-1引いとけばいい
厳しい環境で上限が一桁ってわかってるなら配列のほうがええんやないの
某ゲーム機の某って何っすか?
>>371 アホ。内部表現が0じゃなくてもintにキャストすれば0になることは保証されてんだあよ。
>>374 C or C++ 規格のどこで?それとも特定のコンパイラの話?
ゼロをポインタに入れるとヌルポは保証されてるのに逆はだめなの?
逆が駄目なのは、無茶なキャストを入れないとコンパイル通らないあたりで察しろ。
int* p = nullptr;
if(p){
なにか
}
これはもしかして未定義になりますか?
なるわけがない
いいかげんにFAQ読めよ初心者どもw
384 :
デフォルトの名無しさん:2011/10/13(木) 15:33:05.74
while(1){
a++;
}
WindowsだとSleep(1);挟まないとCPUが100%に張り付きますが、
Linuxだと挟まなくても張り付きません。
そんなもんなんですかね?
Linuxではそこのところ特に気にしなくでもOKということでしょうか?
・最適化で消えている
・マルチコアのCPU使用率の見方を間違えている
Windowsでもプロセスの優先度とか同時に動いてる他のプロセスとの関係で状況が変わるだろ
Windowsアプリでどうしてもそこでプログラムを強制終了させないとダメ
っていう場合はexit、abort、terminate、その他、どれが一番マシですか?
388 :
デフォルトの名無しさん:2011/10/14(金) 23:56:58.18
PostQuitMessage
デニス・リッチーを復活させるにはどのようなコードを書けばよろしいでしょうか。
未定義コード実行して運が良ければ復活してもおかしくないよ
i = i++; とかか
392 :
384:2011/10/15(土) 09:01:13.81
>>385-386 ありがとうございます。
Windowsではタスクマネージャーで確認すると、1つのCPUコアが100%に張り付きます。
Linuxではtopコマンドで当該プロセスのCPU使用率が0.1%とか0.2%です。
趣味プログラムなので当面WindowsのみSleep挟む方向でやってます。
>>391 その式をHevensコンパイラ1.7に書けても
ストイコリッチーしか復活しないぞ。
しかも、左手左足がついてなかった。
>>393 死者を甦らせる方法は今の所誰一人成功していないぜ
蘇生術で生き返った人はたくさんいるお
心停止した直後なら除細動器で生き返る事もあるな
脳死したらまず無理だ
冥界のC言語でプログラムすれば、死者もよみがえる。
黒魔術APIがあれば数行で作れるのに
鼻からデニス
ゲームプログラマになる前に…の5章(シーケンス遷移)で困ってます。
サンプルのプログラムではSequenceファイルの中にGameファイルがあり、
SequenceとGameファイルの中にはいくつかcppがあるのですが、
これを自分で一から作ろうと思ったらどうしたらいいのでしょうか?
例えば、
新規プロジェクトを作成→その中にSequenceファイルを作成→Sequenceフォルダの中に
cppを作成→Sequenceフォルダの中にGameフォルダを作成→その中にcppを作成。
といった手順で作成するのですが、コンパイル出来ません。
本にはプロジェクト内部にディレクトリが構成されているので、
プロジェクトのディレクトリをインクルードパスに指定してやらないといけないと書いてありますが、
あまり意味が分かりません。
ちなみにインクルード出来ない部分は
#include "Sequence/Game/〜.h"です。
ソリューションフォルダ
プロジェクトフォルダ
Sequenceフォルダ
*.cpp
@エクスプローラーから上のようにファイルを作成
AVC++を開く
B画面左のソリューションエクスプローラーの該当プロジェクト名で右クリック
C追加→既存の項目→さっき作ったファイルを指定
$(ProjectDir)を追加のインクルードディレクトリに追加
もしかしてVC++2008からではフォルダは追加出来ないのかな?
VC++上でフォルダを作るんじゃなくて、新規プロジェクトのフォルダ内に
Sequenceフォルダを作ればいいんですよね?
>>402 それって
プロジェクト → プロパティ → C/C++ → 全般 → 追加のインクルードディレクトリ
に書けばいいんですよね?本に載ってあったんでそのまま書いたんですけどダメ
でした。
エラーはこんな感じで出てます。
未解決の外部シンボル "public: __thiscall Sequence::Game::Parent::~Parent(void)" (??1Parent@Game@Sequence@@QAE@XZ) が関数
>>404 cppの方の名前空間指定を間違えていないか?
>>405 丸々コピーして試したので間違ってないと思います。
407 :
400:2011/10/16(日) 11:17:28.92
昨日、質問させていただいたものです。
あれから調べてみたのですが、VC++上でフォルダを作成しても
Windowsの上では作成されないので、Windows上でも同じように
フォルダを作成し、VC++上と同じようにフォルダを配置すればいいんですよね?
それから、$(GAME_LIB_DIR)\Sequence1\include、だけを追加のインクルードディレクトリに
追加したときには、
fatal error C1083: include ファイルを開けません。'Sequence/Parent.h': No such file or directory
fatal error C1083: include ファイルを開けません。'Sequence/StageSelect.h': No such file or directory
といった感じのエラーが出たので、追加のインクルードディレクトリに$(ProjectDir)を追加しました。
すると先ほどのエラーは消えたのですが、今度は
未解決の外部シンボル "public: __thiscall Sequence::Game::Parent::~Parent(void)"(??1Parent@Game@Sequence@@QAE@XZ) が関数
"public: void * __thiscall Sequence::Game::Parent::`scalar deleting destructor'(unsigned int)" (??_GParent@Game@Sequence@@QAEPAXI@Z) で参照されました。
未解決の外部シンボル "public: __thiscall Sequence::Game::Parent::Parent(int)"(??0Parent@Game@Sequence@@QAE@H@Z) が関数
"public: void __thiscall Sequence::Parent::update(void)" (?update@Parent@Sequence@@QAEXXZ) で参照されました。
と出ました…こんな事も分からない自分に涙が出そうです…
extern "C" が抜けているのではないか
>>407 Parent.cpp,Parent.cxx,Parent.ccなどがあるだろうから
それをプロジェクトに追加
410 :
384:2011/10/16(日) 15:58:23.91
今日お昼ご飯を食べながらなんとなくtopコマンドで見ていたら
Linuxでも100%に張り付いていました。
お騒がせしました。
スレッド内部のループ終了条件のためにフラグ変数is_not_endを共有して
while(AtomicChack(is_not_end)) // 他のスレッドがAtomicSet(is_not_end, false)を実行するのを待つ
{
// 何かする。空ではない
} ;
って書いていてるんだけど
while(is_not_end)
{
// 何かする。空ではない
} ;
こういうふうに書き換えたらまずいですか?
412 :
デフォルトの名無しさん:2011/10/18(火) 20:51:35.06
排他処理の問題があるからまずい
>>411 短くいえば、ダメ
もう少し長く言うと、アトミック性、コンパイラの最適化、メモリの可視性の問題を
全部は解決できないからダメ
C++11ではその目的のためにstd::atomicというのが導入されますた
他の(もっと高級な)言語では、単にその変数をvolatileと宣言しておけばいい
場合もあるけど、C/C++では違います(volatileはあるけどメモリの可視性は
保障されない)
414 :
デフォルトの名無しさん:2011/10/19(水) 17:56:53.59
もういいよそういう規格策定者だけの自己満足で誰も得しない機能拡張
流れ的にはどう見てもC++11のことでは
template <class D> class A : noncopyable<A<D> >
{
public:
A(void)
{
static_cast<D *>(this)->Func() ; // Bの構築が完全に終わってから呼びたい
}
} ;
class B : public A<B>
{
public:
void Func(void)
{
// これはBが完全に構築されてからでないと呼び出してはいけない
}
} ;
なんとかしてコンストラクト時に自動で呼ばせたいんですがいい方法はないでしょうか
B Make(void) { B b; b.Func(); return b; }
のようにファクトリを使うのはコピー不可なので無理です
Bのコンストラクタで呼び出せば?
>>417 ファクトリでコピーじゃなくてshared_ptrででも返すのは?
void君て丸っきりおバカでは無いにしろ
ADHDとかADDを指摘された事無い?
>>420 むしろADHD くらいの奴の方が化ける可能性がある。化けそこなうことも多いが。
とにかくみんないっしょじゃつまらん
namespace hoge { // 既存のライブラリ関数。変更できない
template <class A1> void func(A1 const & a1) ;
template <class A1, class A2> void func(A1 const & a1, A2 const & a2) ;
template <class A1, class A2, class A3> void func(A1 const & a1, A2 const & a2, A3 const & a3) ;
}
namespace Fuga { // アプリケーションで使うラップされた関数
template <class A1> inline void Func(A1 const & a1) { hoge::func(a1) ; }
template <class A1, class A2> inline void Func(A1 const & a1, A2 const & a2) { hoge::func(a1, a2) ; }
template <class A1, class A2, class A3> inline void Func(A1 const & a1, A2 const & a2, A3 const & a3) { hoge::func(a1, a2, a3) ; }
}
名前規則に合わせるためと後々の差し替えの可能性を考慮して
上のように既存の関数の薄いラッパーを書いたんだけどオーバーロードがたくさんあるとめんどくさい
これをtypedefのように一発で置換する方法はないだろうか?
c++/clrのwindowsアプリケーションで作成している時に
デバッグにコンソールを開いてやりたいのですが
コンソールを開くにはどうすればいいのでしょうか?
thx
デバックしやすくなっわ!
#include <windows.h>
#ifndef NDEBUG
#include <iostream>
#endif
#ifndef NDEBUG
int main(void) {
HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(0);
#else
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE , LPSTR , int) {
#endif
#ifndef NDEBUG
std::cout << "Debug Msg" << std::endl;
#endif
return 0;
}
>>423 C++11 の variadic templates でなんとか。
すみません。計算符号の差し替えを実現するにはどうすれば良いのでしょうか?
以下のようにしたのですが、#undefと#defineは条件式内で使っても無意味なのか、変数aが1でも2番のマイナスになります。
計算式の種類分、コードを書き出すしか手は無いものなのでしょうか?
#define HUGOU
//上だけグローバルスコープ、以下は関数の中
switch (a) {
case 1: //加算
#undef HUGOU
#define HUGOU +
break;
case 2: //減産
#undef HUGOU
#define HUGOU -
break;
}
int result = 7 HUGOU 5; // プラスのはずがマイナスに。
430 :
429:2011/10/30(日) 15:22:14.77
>>429 誤
#define HUGOU
//上だけグローバルスコープ、以下は関数の中
正
#define HUGOU +
//上だけグローバルスコープ、以下は関数の中
コンパイル時と実行時がごっちゃになっている
>>429 #defineとかはコンパイル前に処理される
加算、減算の関数を作って呼び分けるのが楽なんじゃね
>>429 つ
>>431 #define はプリプロセッサにより、コンパイラに渡る前に消える。
>>429 をプリプロセッサを通ると次のようなコードになる(はずである)。
switch (a) {
case 1: //加算
break;
case 2: //減産
break;
}
int result = 7 - 5;
>>433 今のほとんどのコンパイラはプリプロセッサ内蔵だから正確には
コンパイラに渡る前に消えるじゃなくてコンパイラ内部で消すだろ
435 :
429:2011/10/30(日) 16:51:44.23
>>431-434 定数がちゃんと文字に置き換わるんですから、定数の宣言は当然それより前に処理されますよね。。
編集時にミスが起こり難い様に工夫しながら別々に関数にする事にします。
ご助言、ありがとうございました〜
>>434 bcc32/cpp32: Borland C/C++ Preprocessor
gcc/cpp-3or4.exe
この二つは別プロセスで起動されるようですね。
>>435 #define とか #include とか #if/#ifdef/#elif とかはプリプロセッサが処理する。
ソースコードは、
(1)プリプロセッサ
(2)...(n) コンパイラ (何段階かあると思う)
(n+1) リンカ
と形を変えながら渡って最後に実行可能ファイルに変容する。
>>429 のコードで#define で定義された HUGOU はコンパイラに渡る前に - に置き換えられている。
コンパイル前には、switch 文の中の各 case には、break; 文しか記述されていない。#define そのものはコンパイラには渡っていない。
コンパイラにプリプロセス結果を出力する機能があるはずだから
実際やってみるとよくわかる
>>436 お前本当に何も知らないんだな
cpp32.exeはトライグラフを内部で処理するとコンパイルが遅くなるから
その部分をくっつけて外に出しただけだ
つまりお前はEmbarcaderoの正規ユーザーではなく割れ厨って事がバレバレ
>>438 いつぞや、私のソースを毎回 bcc32 -v -vG でチェックされていた方ですか?お久しぶりです。
>お前本当に何も知らないんだな
いろいろと解説ありがとうございます。
>つまりお前はEmbarcaderoの正規ユーザーではなく割れ厨って事がバレバレ
毎度のことながら、論理が飛躍していませんか?
┐(´д`)┌ヤレヤレ
>いつぞや、私のソースを毎回 bcc32 -v -vG でチェックされていた方ですか?お久しぶりです。
(゚Д゚)ハァ?何勝手に決めつけてんの?
説明書を読めない==説明書を持っていない==割れ厨ですがな
Visual C++ 2010 のコンパイラ CL.exe はプリプロセッサ内臓だね
/E オプションとかでプリプロセス結果を見られる
struct tagHandle ;
typedef tagHandle * Handle ;
shared_ptr<remove_pointer<Handle>::type> p ;
tpedef int Handle ;
shared_ptr<???> p;
↑どないしましょう?
shared_ptr<Handle> p(new Handle(GetHogeHandle()));
とか
コンパイル時にポインタか判定するメタなアレをアレすれば
スゲー意味不明なんだけど
自演?
>>442 pointerという名のtypedefメンバを定義したデリータを指定すればT*型でないものを保持・処理するようになる
#include <iostream>
#include <memory>
typedef int Handle;
Handle get(int v) { return v; }
void release(Handle & h) { std::cout << "release:" << h << std::endl; }
struct handle_deleter
{
typedef Handle pointer;
void operator() (Handle & h) const { release(h); }
};
int main()
{
std::unique_ptr<Handle, handle_deleter> p1(get(100));
return 0;
}
>>443の方向で
std::shared_ptr<Handle> handle_factory()
{
return std::shared_ptr<Handle>(new Handle(getHandle()), [](Handle * p) { releaseHandle(*p); delete p; });
}
std::shared_ptr<Handle> p = handle_factory();
とか
std::sortはクイックソートで実装されているでよい?
もしそうならどこかで規定されてるもの?
いいえ
自演にも最低限必要とされる知能レベルが有る事を知った
class CHoge {
int *p ;
public:
} ;
のポインタpの中身ってCHoge.(*p)とかじゃなくて *CHoge.pなんだな
何かしっくりこないんだが
つーか、要は * (CHoge.p) だ。
454 :
デフォルトの名無しさん:2011/11/10(木) 10:24:49.55
Visual C++〈1〉はじめてのWindowsプログラミング (プログラミング学習シリーズ) 山本 信雄
を読んでVS2010でWin32を使ってみたのですが、いきなり躓きました。
以下の通りに書いてみたのですが、メッセージボックスに何も表示されません。(コメント行は原文です)
http://codepad.org/Ca89uaSG この場合、何がいけないのでしょうか?
すいませんが、よろしくお願いします。
455 :
デフォルトの名無しさん:2011/11/10(木) 10:35:31.48
LPWSTR s = NULL; ←ココ
456 :
454:2011/11/10(木) 10:41:37.50
確かに不正なポインタと表示されますが、どのように初期化すれば良いのでしょう?
LPWSTR s = L"";
と、宣言すればポインタは取得しているのですが、やはりメッセージボックスには何も表示されませんでした。
457 :
デフォルトの名無しさん:2011/11/10(木) 10:47:47.90
458 :
454:2011/11/10(木) 11:56:26.59
>>457 これだと動きますね。
LPWSTR s = L"テスト";
にして
>>454を動かすと、「テスト」が表示されますし。
コピーの方法に問題があるのでしょうか?
原文に戻してstrcpyにすれば、とりあえずsには文字列が入りますが、メッセージボックスが使えないですし。
文字列を変換すれば良いのでしょうが、lstrcpyが使えない理由がわからないままなのが気になります。
ポインタ変数と配列の違いを勉強した方が良いと思う。
>>454 自分もその本読んだけど、悪いことは言わん、今すぐ捨てろ。めちゃくちゃだから、その本。
1巻のWin32APIを学びたいならプログラミングWindows(上下)しかない。
値段は高いけど、これ読むかMSDN読む以外にWin32APIを「正しく」理解する方法はない。
2巻の「オブジェクト指向」は「名詞と動詞」みたいな有害なだけの化石概念が出てくる。捨ててよし。
3巻のMFCはクソの極み。読むだけで死ぬ。開く前に捨てよう。
462 :
デフォルトの名無しさん:2011/11/10(木) 13:04:35.72
463 :
454:2011/11/10(木) 13:06:06.50
>>459 一度そこを見ましたが・・・よく考えたらUnicodeになってました。
マルチバイトにしたら動きました、ありがとうございます。
>>460 似て異なる物だとは思うのですが、正確に把握出来て無いですね。
ググってみます。
>>461 流石にVC6はもう古いですかね?
評価が高いから、この本で勉強してみようと思ったのですが・・・。
MFCを覚える前にWin32APIを理解する必要があるかと思って、触ってみました。
>>463 LPWSTR は long pointer wide string の意味。
つまり、wchar_t *。
wchar_t *s = NULL;
wcscpy( s, L"おぱんぽん" );
なんてやったらメモリぶっこわして終わりなのはわかるでしょ?
wchar_t s[ 100000 ];
wcscpy( s, L"おぱんぽん" );
のように書かないと。
そしてもう一つ。残念なことにいまのところ、
まだWindowsアプリケーションはUnicodeで万事OKとは言いがたい。
従って、TCHARとTEXTを用いるべき。例えば…
TCHAR s[ 100000 ];
_tcscpy( s, TEXT( "おはようございます" ) );
iRet = MessageBox( NULL, s, TEXT( "MsgBox" ), MB_OK );
>流石にVC6はもう古いですかね?
さすがに標準から逸脱しすぎて、現代的なテクニックの大部分が使えなくなってる。
>評価が高いから
2ちゃんの某スレでそうだったので自分も買ったのだが、単なる提灯書き込みであったことが後に発覚。
>>464 >まだWindowsアプリケーションはUnicodeで万事OKとは言いがたい。
UnicodeでNGになるのってどんなこと?
>>464 プリプロセッサでワイド文字とマルチバイト文字を切り替えなきゃいけないのって、
たとえばどういう状況?どういうときにそれを気にすればいいの?
よし、WindowsではUTF-8の使用は禁止だ。
>>464 倣うなら、WCHAR s[100000];
469 :
454:2011/11/10(木) 14:05:35.86
>>464 wchar_t *s = NULL;
wcscpy( s, L"おぱんぽん" );
これだとポインタをNULLにしているので初期化になっておらず、
確かに場所が無いから入れようが無いのはわかるのですが
wchar_t *s = "ぬるぽ";
wcscpy( s, L"おぱんぽん" );
なら、ポインタの場所があるから上書きされる・・・と思ったのですが違うのですね?
配列にして領域を確保しないといけないと言ったところでしょうか?
またこの場合、"おぱんぽん"はどこにコピーされているのでしょうか?
あ、やばい
スレ間違えました。
ごめんなさい。
474 :
454:2011/11/10(木) 17:28:06.77
>>473 なるほど、constやdefineのように固定値になっているのですね。
書き換えるなら最初から書き換え用の領域を確保が必要と。
ありがとうざいました。
GCC、VC++でマクロと標準のincludeを展開せずに、ソースコードを一枚にまとめるにはどうしたら良いですか?
プリプロセッサの機能と思うのですが出来ないです。
標準のincludeの行を消してプリプロセスする
マクロはわからん
仮引数を持つコンストラクタで初期化する場合,
CHoge obj ( ) ;
と書くのではなく,
CHoge obj ;
と書くのはデフォルトコンストラクタが関係したりしています?
↑仮引数ではなくデフォルト引数ですた
それが関数宣言とみなされるのがたまらなく嫌だった
僕はそのことに耐えられなかったのだ
括弧を省略したのにはそんな訳があった
>>480 言われてみれば確かにCHogeを返す引数なしのobjという関数に見える
ということは,デフォルト引数ありで引数省略のコンストラクタと,引数なしのコンストラクタとは共存できないのね
スッキリしたthx
コンパイラgcc 2.95.3です。
void
fetch_info(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fputc('\n', stderr);
}
という関数をコンパイルすると、
va_start(ap, fmt);で
discards qualifiers from pointer target type
というワーニングが出ます。
エラー部のマクロを展開すると、
( ap = (va_list)((long *)&( fmt ) + __extension__ ( __builtin_classify_type(*( __typeof( fmt ) *)0) == __real_type_class ? sizeof (*( __typeof( fmt ) *)0) > sizeof (double) ? 4 : 2 :
__builtin_classify_type(*( __typeof( fmt ) *)0) == __record_type_class || __builtin_classify_type(*( __typeof( fmt ) *)0) ==
__union_type_class ? (sizeof (*( __typeof( fmt ) *)0) +
sizeof (int) - 1) / sizeof (int) :
__builtin_classify_type(*( __typeof( fmt ) *)0) ==
__integer_type_class && sizeof (*( __typeof( fmt ) *)0) >
sizeof (int) ? 2 : 1 ) )) ;
あまりにも難しくて理解できないのですが、
どこが悪いのでしょうか?
実装の都合で、何か悪くなくても警告される悪寒。
gcc2.95って10年以上前か
ずいぶん古いの使ってるんだな
> (long *)&( fmt )
const char * * を long * にキャストするとconstが無くなるけどそれでいいのかいって警告
この場合問題ないから無視するかGCCのバージョンをあげな
学校だと古いコンパイラ使わされるんだよな
RedHat9とかのころかなぁ
教授って人種はもう何年も前の世界に取り残されてるからな
普通にfotranしか知らない教授とかいるからな
超初心者ですみません
vc++とかでプロジェクトの設定をする時に
includeのパスを通すのは分かるんですが
libにパスを通す意味ってなん何でしょうか
ライブラリのディレクトリパスを指定する、というのは分かるのですが
ライブラリのファイルを読んでくることの必要性というのは何なのでしょうか
includeは、
#include <stdio.h>
などでよく使うので馴染みがあるのですが
初心者ゆえライブラリというものをどういう時に使うのかが分からないのです。
>>490 #include で宣言を libで処理の実体を頂いてくると考えておくといい
ヘッダーで完結するライブラリもあるから、
必ずしもこのパターンになるとは限らない。
例えば、
void hoge(); /*宣言 ヘッダ*/
void hoge() /*実体 lib*/
{
}
判り難い説明だな。
>>490 ライブラリってのはコンパイル済みのソースみたいなもんです
printfの中身とかが入ってます
で、exeを作るときにはprintfの中身が必要になることもあるのでそれのおいてある場所を指定するわけです
printfの入ってるようなlibならvcの場合は勝手に取ってきますが
そういう標準なやつでないものを使いたいときにその中身が入っているファイルのあるパス、およびそのファイル名を指定します
objとlibはナニが違うんですか?
>>490 stdio.h だけじゃなくて、
本当は stdio.c (に相当する物)も必要だから。
C/C++プログラムが作られる工程
(3つのソースからhello.exeをつくる場合)
コンパイル:
test.c --> test.obj
test2.c --> test2.obj
main.c --> main.obj
リンク:
test.obj test2.obj main.obj --> hello.exe
* リンク: 複数の.objを、1つにまとめる。
.objはVCプロジェクトのフォルダ内にあると思う。
ライブラリもプログラムも.obj形式の一種。
(ライブラリはwindowsだと.libファイル。)
ヘッダーファイルは一覧しか書いてない!
だから、stdio.obj に相当するものが必要。
それがライブラリ!
なんでわざわざobjとlibを別の名前にしたんですか?同じなのに?
ちなみに
test.obj test2.obj main.obj --> main-obj.obj
なんてこともできます。
498 :
デフォルトの名無しさん:2011/11/13(日) 23:16:40.65
>>494 libはobjのコレクションだ。
objの状態でも使えるけど、libにまとめておいたほうが管理しやすい。
obj専用のアーカイブファイルみたいなものだね。
>>496 .lib は後処理して綺麗にしたもの。
exeもobjを綺麗にしたもの。
>>494 objもソースの中身だけど 各コンパイラが勝手に作った形式で
libは他のコンパイラでも使えるように共通化されたものかもしれない
objは自分用でlibは公開用とでも思っておけば。
>>502 .exeと.lib、.selfと.aにしか興味ないんで認識あまかったかw うふふ。
>>495 じゃあ
stdio.hをインクルードして
#include <stdio.h>
int main() {
printf "helloWorld";
}
というファイルをhello.cとして保存した後、
コンパイルした場合は、studio.cとhello.cをリンクするような動作をしているということでしょうか
>>504 そのとおり。
よく使うもの(標準ライブラリなど)は、
必要な分だけVCが勝手にやってくれてるだけ。
本当はリンクの指定も自分で行わないといけない。
逆にそれらをリンクしない設定もできる。
もちろん必要なのにリンクされない場合、
リンカが「足りないよ」ってエラーを出す。
>>504 考え方はあってるがリンクするのはソースファイルじゃなくてhello.cをコンパイルしたhello.objと
stdio.libの中のprintf.obj(ライブラリの作成者が事前にprintf.cをコンパイルしておいたもの)とかだけどな
>>503 .selfってどの環境なんだろ
.out と .a ならわかるんだけれど
>>506 なるほど、わかりやすいです。
コンパイルするとobjという形式になるんですね
>>509 なんでそんなマイナーな環境持ち出したの?
知能指数が他人より劣っているからでしょう
クラスAがhoge()をもってて、
クラスBはクラスCを継承してhoge()をオーバライドしていて、
クラスCはクラスBを継承してhoge()をオーバライドしていて、
クラスDがクラスCを継承しているとき、
クラスDでhoge()を記述しようとしたら、クラスAのhoge()と全く同じことに気がつきました。
この際に、クラスAのhoge()を再利用して、コード量を減らすことってできます?
よろしくお願いします。
514 :
512:2011/11/14(月) 06:13:04.72
>>513 申し訳ない
×クラスBはクラスCを継承してhoge()をオーバライドしていて、
○クラスBはクラスAを継承してhoge()をオーバライドしていて、
そういうことではなくて、コードを書いた方がいいということです?
実はDはAを継承すればすむとか。
ともあれ、まずはそのままA::hogeとまったく同じD::hogeを実装しておいて
リファクタリングすればいいと思う。
クラス分割がうまくいってないんじゃないかなと。
>>512 D::hoge() の中で A::hoge() と明示的に A:: を付けて呼び出せば改めて
書く必要は無いけど、 A::hoge() の実装をいじったときに D::hoge() まで
影響を受けるようだと困るかもしれない。
>>509 青い背景にすると焼き付きが目立つって噂のあのゲーム機?
C++の「ハンドル」って何ですか?
ポインタのことを理解していないと分からないものですか?
いいえ
>>518 え、マジ?そんな噂あるの?
今品薄で俺のところまで最新の実機来てないから本物の焼き付きとかわかんねです
>>519 うちの会社では管理してる物にアクセスするIDとかをハンドルって呼んでるなぁ
たとえばシステムが管理してるものの入った配列があってその3番目のにアクセスしたいときのハンドルは2、もしくは3になってたりする
(実際は安全のためもうちょっと工夫したのを使ってるんだけど)
めんどいときはnewしたポインタをそれっぽいのにキャストして返して、それにアクセスする関数でもとのにキャストしなおして使うとか
C++の「ハンドル」ってのはなにかはシラネ
もしかしてHWNDとかそっちの話?
523 :
482:2011/11/15(火) 01:53:08.69
お世話になっております。
(va_list)((long *)&( fmt )
の場所を
(va_list)((const long *)&( fmt )
や
(va_list)((long * const)&( fmt )
や
(va_list)((const char *)&( fmt )
や
(va_list)((char * const)&( fmt )
とやってみましたが、無理でした。
__builtin_classify_type(...
は引数の始まりを計算しているから触らないでよいんですよね?
>>const char * * を long * にキャストするとconstが無くなるけどそれでいいのかいって警告
gccのバージョンをあげるのは無理な状態です。
(ソースからコンパイルできる自信が無い)
ワーニングを無視するのも、少し心配です。
constを保ったままキャストする方法は無いのでしょうか?
fetch_info(const char *fmt, ...)
からconstを取る。
Cのリテラルはconst char *じゃなく、char *だったはず
これが正しいかどうかは識者が後ほど突っ込んでくれるはず。
よくわからんけどif文に展開してみた
if( __builtin_classify_type( const char* ) == __real_type_class ) {
if( sizeof( const char* ) > sizeof( double ) ) {
ap = (va_list)(long *)&(fmt) + __extension__ 4;
}
else {
ap = (va_list)(long *)&(fmt) + __extension__ 2;
}
}
else {
if( ( __builtin_classify_type( const char* ) == __record_type_class ) || ( __builtin_classify_type( const char* ) == __union_type_class ) ) {
ap = (va_list)(long *)&(fmt) + __extension__ ((sizeof(const char*) + sizeof(int) - 1) / sizeof (int));
}
else {
if( __builtin_classify_type( const char* ) == __integer_type_class ) {
if( sizeof( const char* ) > sizeof(int) ) {
ap = (va_list)(long *)&(fmt) + __extension__ 2;
}
else {
ap = (va_list)(long *)&(fmt) + __extension__ 1;
}
}
else {
ap = (va_list)(long *)&(fmt) + __extension__ 1;
}
}
}
よくわかんないけど(long *)を(const long*)にしたところで
(va_list)のキャストでまたconstはずしてるからなんか言われてんじゃないの?
コンストラクタ
初期化
>>526 コンストラクタと初期化子の並び
構造体 planet の変数 equatorial_axis は int 型でC由来の組み込み型。
std::string と std::vector はデフォルトで空初期化されるけど
int 型は明示的に指定しないと初期化されない。(中身が不定)
それで : equatorial_axis() と初期化子を書いてゼロ初期化している。
>>521 開発機で白文字放置したら簡単に…って噂
ゼビウスとかきっとヤバイ
530 :
526:2011/11/16(水) 12:40:44.77
>>527,
>>528 >それで : equatorial_axis() と初期化子を書いてゼロ初期化している。
とてもわかりやすかったです。ありがとうございます。
どうして、「equatorial_axis() 」という空っぽの関数を書いているのかと悩みましたが、初期化する場合の書き方でしたか。
追加でもうひとつお願いします。
try{}catch{}で例外を捕まえたときに、
その例外がどんなものなのかコンソールに表示したいのですが、
javaのSystem.out.printlnのように簡単に表示することは出来るのでしょうか?
とりあえず、cout <<としてみたところ、Javaのような変換はされませんでした。
Javaだと暗黙のtostringみたいなのが呼ばれるんかな。
stringへのキャスト演算子をオーバーロードすればどうにかなるだろうか。
533 :
530:2011/11/16(水) 13:14:38.71
>>531 即レスありがとうございます。
今回catchした例外は、「boost::property_tree::ptree_error」配下の何かなのですが、同じ方法ではダメなようでした。
せめてなんという例外なのか表示したく、近所のソースを追うと、文字列を詰めているコードがあったので、coutでいけるんじゃね?と思いましたが、ダメでした。
後からの情報追加で申し訳ないです。あと隠れている情報はないと思います。
再度お願いします。
xmlのフォーマットで書かれたテキストファイルを読み込みたいのですが、
そもそも、ファイルの内容がXMLとしておかしくないかチェックしてくれる便利なライブラリを紹介いただけないでしょうか?
<root>
<aa>えー</cc>
<bb>びー</bb>
</root>
rapid_xml(もしくは、boost::property_tree)でxmlのパースができることを見つけました。
が、<aa>の閉じタグが何故か</cc>になっているのでパースエラーになってほしいのですが、問題なしにされてしまいました。
ここまでのチェックは、他のライブラリも含めて、してくれないものなのでしょうか?
欲を出すと、boostライセンスのように取扱が簡単なものがよいのですが…。
MSXMLも試してみます。引数の意味を理解できなかったので後回しにしていました。
(530ですが、別件なので別名で書き込みます。)
>>533 what()でなんかでるだろ
catch(boost::property_tree::ptree_error & e)
{
cout << e.what();
}
ありがとうございます。
解決しました。
…なるほど、std::exceptionにwhat()があって、各例外クラスはそれをオーバーライドするのですか。ふむふむ。
隠れてる情報ってなんだろう…
メンバの引数と返り値がすべてwindows.hに有る型orポインタ
のインターフェースをDLLで実装して生成(破棄もDLL側で)
ってコンパイラ間の移植性ありますか?
たとえば上のようにVC++でコンパイルしたDLLをロードして使う方のEXEはMinGWでコンパイル的な感じで
539 :
デフォルトの名無しさん:2011/11/16(水) 19:59:33.01
boostのようにクロスプラットフォームで壁紙の変更を行えるライブラリはないでしょうか
なければ作りたいと思うのでコンパイル時にwindowsとlinuxで別のコードを使うようにする方法をおしえてください
>>534 parse<parse_validate_closing_tags>(...)
他のフラグも幾つかあるので、一度マニュアルを読んだほうがいいよ
コンストラクタって何なんですか?
数値を初期化するためのものなんですか?
初期化以外には使われないのですか?
コンストラクタがあると、どういう時に便利なのですか?
僕みたいなバカにも分かるようにセーラームーンの登場人物で例えて教えて下さい
コンストラクタはムーン・プリズムパワー・メイクアップみたいなもん
ムーン・プリズムパワー・メイクアップが無いとセーラー服美少女戦士を構築するために
毎回セーラー服や装飾品の数々をひとつずつ装備していかなければならず、どうしても
たまには髪のセットを間違えたりティアラを忘れるなど重大な問題を起こす可能性がある。
一連の手順をまとめて自動化したムーン・プリズムパワー・メイクアップは非常に大切
なのであるかもしれない。
>>542 結局のところ薔薇を投げることで、タキシード仮面が現れたことに気づいてもらえるわけだが、
たとえば、なるちゃんがタキシード仮面を視認した後、薔薇を投げるというルールにすると、
なるちゃんがたまたま近くにいないと美奈子が困るじゃん。
なので、タキシード仮面はなるちゃんがいなくてもいいように毎回自分で投げることにしてる。
これで美奈子の安全が守られる。
>>545 美少女戦士クラス
...コンストラクタ(ムーンプリズムパワーメイクアップ)
.......髪
.......ティアラ
.......セーラー服
月野うさぎ.ムーンプリズムパワーメイクアップ
=美少女戦士セーラームーン(セーラー服、ティアラ、髪)??
ってこと?
ムーンプリズムパワーメイクアップをしても、キャラごとに服や髪の色は違うけれど
それはどう対処するのでしょうか
質問です。
struct data{
char name[20];
}mydata = { "nanasi"};
struct data *p;
p=&mydata;
printf("hello! %s \n",p->name);
とやると、hello ! nanasi
と表示されると思うんですが、
これを
char *moji = "hello! %s \n";
printf(moji,p->name);
とやった場合、
hello ! nanasi
と表示させることは可能でしょうか?
もし不可能な場合、
printfに文字列へのポインタしか渡せない場合、
"hello! %s \n",p->name
をどのように展開して文字列へのポインタに代入してやれば
良いのでしょうか?
文字列へのポインタを渡してるけど、何と勘違いしたの?
>>549 ん、出来ます?
ちょっと今コンピュターを触れる
環境になくて、自信なかったのですが
552 :
548:2011/11/17(木) 12:15:51.26
あらー、便利なサイトをありがとう
ございます。
もうひとつ質問なんですが、
char *moji = "hello! %s \n,p->name";
printf(moji);
とやった場合は無理ですよね。
何とかして%sにp->nameを展開?
した状態で文字列へのポインタとして
printfに渡したいんですが、
その場合はstrcpyを駆使しないと
難しいでしょうか?
もしかしてsprintf?
556 :
デフォルトの名無しさん:2011/11/18(金) 00:10:50.80
なぜ代入演算子はフレンド関数でオーバーロードできないんでしょうか?
friend ob operator=(ob ob1, int i) {
ob tmp ;
tmp.x = ob1.x + i ;
return tmp ;
}
と定義できて,ob2 = 10 ;と書けそうなものですが.
>>556 そういう書き方が出来ると勝手にクラスからむしり取る悪いfriendになってしまうから
あくまでもクラス側でfriendにならないとだめ
freiend は実装側の都合にone write 主義が負けた悪い仕組み
559 :
デフォルトの名無しさん:2011/11/18(金) 00:28:58.35
>>557 確かにVC++2010のコンパイラに,operator=はメンバでなければならないと怒られました.
operator+やoperator-がfriendで定義できることと何が違うんです?
>>559 クラス内で定義もしくは宣言すると引数一つ、相手は自分自身
friendにすると引数二つ、自分と同じクラス
561 :
デフォルトの名無しさん:2011/11/18(金) 00:40:35.12
>>560 それは理解しているつもりです.
ob ob::operator+(ob ob1) ;
friend ob operator+(ob ob1, ob ob2) ;
と書けるならば
ob ob::operator=(ob ob1) ;
friend ob operator=(ob ob1, ob ob2) ;
も書けてもいいのではないかと思ったのでした
暗黙に生成される=があるから勝手に外でoperator=を定義されては困る
friendってunittest以外で有効な場面あるの?
>>561 §12.8.9
A user-declared copy assignment operator X::operator= is a non-static non-template member function
of class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatile
X&.109)
[Note: an overloaded assignment operator must be declared to have only one parameter; see 13.5.3.]
[Note: more than one form of copy assignment operator may be declared for a class. ]
[Note: if a class X only has a copy assignment operator with a parameter of type X&,
an expression of type const X cannot be assigned to an object of type X].
§13.5.3.1
An assignment operator shall be implemented by a non-static member function with exactly
one parameter.
Because a copy assignment operator operator= is implicitly declared for a class if not declared by
the user (12.8), a base class assignment operator is always hidden by the copy assignment
operator of the derived class.
規格で決まっちゃってんのよ
friendは代入演算子=のオーバーロードには使えない
擬似的にはいけるけどね
曖昧でも書けないものかと思ったわけでしたが、規格でそう決まっているなら仕方がありませんね
お付き合い頂きありがとう
friendもiostreamなんかで利点はある。
…と思ったけど、オーバーヘッドとバイナリ肥大を気にしなければ、
templateで対応できるな。
typeid(hoge).name()を使わないで、標準の範囲でクラスの型名を得ることってできますか?
>>569 クラス名を格納する変数を事前定義するか、
ソース解析、バイナリ解析すれば可能だけど、まず無理。
あきらめろ。
C++には規格にリフレクション機能は備わってないからなあ
コンパイラ言語だから不要と判断されたんだろう
gcc拡張なら__FUNCTION__, __PRETTY_FUNCTION__はあるけど
さすがにクラス名はない
というかもしあったらリンクした時たまたま同一のクラス名でファイル内だけに
通用したい場合もぶつかっちゃうっしょ
>>571 RTTIはまさにC++のリフレクションの実装だろ。
それを使わないで実行時情報を取得するには?って質問だから、
代わりに静的解析使えば?って言っただけに過ぎないんだが。
RTTIは仮想関数を使わないで実現したいデザパタを書けるように
用意されたもんだけどな
サイズならsizeofで得られるしメンバポインタもあるしtypeid().name()で
返される文字列は環境依存だし結構使えない
>>573 だからそれをリフレクションと言うんだよ。
コンパイラが違うともう返される文字列が同じとは保証されないリフレクションなぞ
使い道が限定されると言ってるだけなんだが
>>575 俺も最初の2行について言及しただけだが。
==と!=しか使えないRTTIは使い道が限られる
JavaやC#と一緒に考えんなよ
578 :
デフォルトの名無しさん:2011/11/18(金) 19:11:33.70
よろしくおねがいします
手持ちの入門書を見ると、関数のオーバーライドのときは親クラスの関数宣言にvirtualをつけるようにと説明されています。
ところが、このvirtualの指定をしなくても親クラス子クラスで同名同シグネチャの関数を作ることができます。
ここで質問ですが、
@このようなvirtual指定しない使い方は、文法的に正しいのでしょうか?(それとも暗黙のルールが適用されてしまっている?)
Aこれもオーバーライドと読んでいいのでしょうか?それとも別の呼び名があるのでしょうか?
Bなぜこの使い方(?)は入門書では割愛されているのでしょうか?(プログラム自体はふつうにコンパイルできて動くのに)
>>578 1 正しい
2 隠蔽。オーバーライドとは挙動が違う。
3 説明が面倒だから
>>582 ありがとうございます
>>580のサイトからさらに飛んだ先のサイトで、オーバーライドと区別して「上書き」という言葉を使っているのを発見しました。
すなおに英語に戻すと、overwriteですが、オーバーライド(override)の日本語訳としても「上書き」は使われています。
やや、用語に混乱があるように思うのですが、実際の現場ではどうなんでしょう?
(「誰も気にしていない」、が一番可能性高そうですが・・・・)
クラス変数はpublicでないとならないのですか?
クラス内のインスタンスメソッドからのみアクセスできるようにしたいのですが。
privateの中に、staticで変数を宣言すると、定義する際に、そんな変数は見付からないといわれます。
@Visual C++ 2010 Express。
よろしくお願いします。
cpp側に
変数の型 クラス名::変数名;
と定義を書かないといけない
class Hoge に対し
Hoge obj; obj.a = 10 等のように使いたいならpublicにしないとダメ。
派生したクラスから基底クラスのメンバを参照したいならprotectedにする。
>>583 新しい関数を作ることで元の関数が使えなくなったりするわけじゃないので
「上書き」と呼ぶのは非推奨
スマン
>>587は忘れて
よく考えたらオーバーライドも元の関数が使えなくなるわけじゃないわw
上書きというより再定義の方がイメージとしては近い気がする
>>578 1 文法的に正しい
2 オーバーライドと読んでいい
3 すごく雑に言うと、非仮想関数はオーバーライドを禁止するセマンティクスを持つため
用語の問題にぶつかったら規格票を読め
…と思って自分も読もうと思ったが、JISの検索サイトで開けない('∀`)
クソJIS死ね
JISは最新のAcrobat Readerを使えと書いてある割には一つ前のバージョンの
Acrobat Readerでないと閲覧出来ない
Acrobat Reader X は NG
規格ってただで見れるんですか?
日本工業規格のものならね。
ansiの方は金払わないと見られなかったと思う。
logicoolのマウスでチルトホイール水平ボタン拾うとき
WndProcからWM_MOUSEHWHEELを拾っえたのですが
setpoint(6.32)起動すると拾えなくなり
setpoint停止すると拾えるようになる
(setpointの設定はデフォルト(左スクロールと右スクロール))
setpoint起動時でも拾えるようにするにはどうすればいいんでしょうか?
とりあえず、Spy+でホイール回転時にどんなWM飛ばしてるか確認してみたら?
WindowsのバージョンによってもWM違うし。
a
a
>>595 M500, Windows7 64bit, Setpoint6.32.7 デフォルト設定(左スクロールと右スクロール) だけど
チルト WM_MOUSEHWHEEL(0x020E) は setpoint を終了しなくても来てたよ?
ただ, X-Mouse Button Control V2.2 では setpoint 起動しているとチルトが反応しないので setpoint が
チルトの何かいじっている可能性は高いと思うけど.
これはとりあえず user.xml の Button Number="6" と "7" の内容(HorzScrollLeftSet,HorzScrollRightSet) を編集して
GenericMouseButton と同じ内容に書き換えれば反応するようになったよ.
SetpointPlus を入れて「汎用ボタン」に設定してもたぶん同じことだと思うけど.
>>579 CSub sub; sub.test1(); // CSub::test1
CBase* pBase = new CSub; pBase->test1(); // CBase::test1
CSub* pSub = new CSub; pSub->test1(); // CSub::test1
//CSub* pSub2 = new CBase; pSub2->test1(); // エラー
僕にはわけがわかりません!
サンプルコード触ってるとクラスのヘッダで
typedef class ClassA {
(中略)
} CLASSA, *LPCLASSA;
と、typedefしてるクラスを見かける時があるんだが
これは何故このようなtypedefをしてるんだろうか。
Windowsプログラムに混ぜて書くときに、見やすくする為か?
それとも慣例か何かか?
それにLPCLASSAのようにポインタを隠匿するメリットって何だろうか。
これは可読性云々って話なんだろうか。
A* obj1,obj2;
obj1->func(); // OK
obj2->func() // NG
ということじゃないか?obj2はAであってA*ではない。
このような誤りを防ぐためにtypedefしているのでは?
typedef HOGE * LPHOGE;
LPHOGE pH = Hoge_Create();
Hoge_DoSomething(pH);
Hoge_Delete(pH);
のように書いておけば
typedef uint_ptr LPHOGE;
と書き換えてもおkで便利だから
spy++は6.0のしかもってないわー
EEにもついていればいいのに
書き換えないとうごかないか・・・
何かいい方法はないかな
>>606 使ったことがないから詳しくは知らないが、UISpyなるツールがあるらしい。
608 :
602 :2011/11/19(土) 19:09:16.90
二次元配列を動的に生成する方法について教えてください。
int a[X][Y]; のような二次元配列をnewして動的に生成したいのですが
ぐぐると、配列へのポインタをnewして、二次元目は二次元の要素数分だけ、
forループでnewする例ばかりいっぱい出てきました。
int** a=new int[X][Y]; <--エラーになる
みたいに簡単に出来ないものかと思い試行錯誤してみたら
void* a=new int[X][Y]; がコンパイルを通りました。
配列へのアクセスは
((int(*)[X])((int*)a))[x][y]=100;
上記のような記述でOKでした。
とりあえずは動作しているみたいなのですが、
これで問題はないのでしょうか。
それともこの方法は間違いであり、ぐぐるといっぱい出てくる二次元目は要素数分だけnewが正解なのでしょうか?
Webで公開しているような方々が、こんな簡単に動的配列を生成する方法を
知らない訳はないのではと思い、きっとどこか間違っていそうな気がしています。
よろしくお願いします。
>>609 そんな混み合った記述よりも内部で一次元配列使って、
アクセスだけ2次元にすればわかりやすい
width * heightの要素をもつ1次元配列(vectorだと横着できる)
int index = width * y + x;
で添え字にアクセスして終わり
template <class T>
class Array2D{...}
とかつくっといてもいいかも
>>609 int (*a)[Y] = new int[X][Y];
612 :
609:2011/11/19(土) 20:10:35.89
>>611 なるほど〜、勉強になります。ありがとうございます。
int (*a)[Y] = new int[X][Y];
と宣言すると
a[x][y]=100;
となりますね。
多次元配列をforループでnewしまくっているばかり出てくるwebの例は
この記述を知らないってことなんでしょうかね。
これは一部のスーパーハッカーしかしらない技術だからな仕方が無いよ
>>612 多段階配列を使いたい場合はやはり個別にnewする必要があるけどな
まずは vector 使えよ。
vector< vector< x > > v;
でいいじゃん
boost::numeric::ublas::matrixでもいいじゃん
618 :
デフォルトの名無しさん:2011/11/19(土) 21:17:03.00
class DebugStream{
public:
DebugStream();
int precision( int );
DebugStream& operator<<( char );
DebugStream& operator<<( unsigned char );
DebugStream& operator<<( int );
DebugStream& operator<<( unsigned );
DebugStream& operator<<( short );
DebugStream& operator<<( unsigned short );
DebugStream& operator<<( float );
DebugStream& operator<<( double );
DebugStream& operator<<( const string& );
DebugStream& operator<<( const char* );
DebugStream& operator<<( char* );
DebugStream& operator<<( const RefString& );
DebugStream& operator<<( const OStringStream& );
DebugStream& operator<<( DebugStream& ( *f )( DebugStream& ) );
DebugStream& endl();
DebugStream& hex();
DebugStream& dec();
void begin();
void end();
private:
class Impl; //ここ
Impl* mImpl;
};
クラス宣言中のクラス宣言?
これはどういう理由があるのですか
pimplでぐぐればまさにその説明があるよ
pImpleパターンです
>>621 たしかに、方言でニキビパターンとも言いますね
Pimpletonパターン
Exceptional C++を読んでいればPimplイディオムを知ってるはず
悪いが良本しか読まないたちなのでな
良本じゃん
お前らって例外に持たせる文字列ってコード内に決め打ちする派?しない派?
例外と assert に関しては決め打ちスルタン
例外用文字列動的に構築してる時にさらに例外起きたら嫌じゃん
起きた事ないけど
フロイトの無知の知ですね
>>629 固定サイズのバッファならだいじょうぶじゃね?
>>631 ソクラテス。「弁明」21B〜をみてね。
でも一種の開き直りにしかみえないのですけれども‥‥‥。
釣りだろ。
良書云々は、良書であることは知っているが、読んでいないんだろ
ぴんぴんぷるぷる。
まぁ、ちょっと大きめのプログラムを組んでいると
すぐPimpleイディオムに行き着く。
初心者ですみません
基底クラスのコンストラクタが 基底クラスからのコンストラクトか
派生クラスから巡ってきたコンストラクトかを
基底クラスのコンストラクタ内で判定することはできますか?
よろしくお願いいたします
そうしたい理由
>>637 基底クラスにフラグ変数を用意して派生クラス毎に初期化リストで代入する値を変えるとか
でもコンストラクタが終了しないとメンバ変数は使用不能なんだよなあ
Base(bool isDerivedClass = false)
Derived() : Base(true)
こうしとけば?
だな
コンストラクタの引数にデフォルト引数として書いて置けばいける
でもなんでそれが必要なんだろう。
ほかの解決方法があるような気がする
以下の二つのコードの違いがわかりません。前者は意図した動作、後者は異常になります。
// 前者
std::string tmpString = xpathExpressionPrefix + std::string("/hoge/foo/piyo/text()");
const char* pc1 = tmpString.c_str();
xpathExpression = BAD_CAST pc1;
xpathObject = ::xmlXPathEvalExpression(xpathExpression, xpathContext);
// 後者
xpathExpression = BAD_CAST (const char*)(xpathExpressionPrefix + std::string("/hoge/foo/piyo/text()")).c_str();
xpathObject = ::xmlXPathEvalExpression(xpathExpression, xpathContext);
キャストがどうしてまずいのかいまいちわからないです。
よろしくお願いします。
(const char*)(hoge).c_str()
typoだったとして、後者は一時オブジェクトだから
前者はconstはがしなのかなぁ
>後者は一時オブジェクトだから
それだ!
そうか…、確かに…。
言葉足らずで申し訳ない。
先に後者のコードで書いて動かしてみたところ、ハンドルされてない例外で停止して、分割していった結果が前者でした。
647 :
646:2011/11/20(日) 06:50:33.47
申し訳ない。
感謝の言葉を忘れてました。
ありがとうございます。
別にtypoじゃなかったねごめん。
>>647わざわざどうもです。
できれば脱Cスタイルキャストを。
>できれば脱Cスタイルキャストを。
指摘を受けてぐぐるして、
c++スタイルのキャストというのを初めて見ました。
ありがとうございます。
VS2010でフォームアプリケーションを作ったのですが他のバージョンのVS環境でも動くのでしょうか?
よろしくお願いします。
マンキツでテストしたら起動しなかったことがある
>>650 対応するランタイムライブラリ(msvcrt.dll系)が入ってない環境では動かないときもある
ソリューションファイルの形式が違うって怒られると思うよ
将来、新しいバージョンが出たときのことを考えているのなら、それは大丈夫
魔法の言葉vcregist.exeだな
>>651-654 想定ではVS2005を考えていたのですがどうやら怪しそうですね。。
とりあえず一度駄目もとで実行さしてみようと思います。
回答頂きありがとうございました!
656 :
653:2011/11/20(日) 18:29:10.76
>>655 ちなみに実行ファイルをほかのマシンで動かすことについての話なら
世の中の一般ユーザはVSなんて入れてないけど、VSで作られたアプリが動作していることを考えれば答えは出る
唯一つ注意するのは、リリースビルドにすること。
newした派生クラスのインスタンスを基底クラスのポインタで取り扱います。
ここで、もうひとつ基底クラスのポインタを作成し、
先ほどnewしたインスタンスの複製を作って、そのアドレスをポイントしたいです。
可能でしょうか?可能であれば方法をおしえてほしいです。
ここで、派生クラスは複数あって、どのクラスがつかわれているかは、わからないです。(もしかして、それを知る方法がある?)
以下がイメージです。
Base* pBase1;
pBase1 = new Derrived; // Derrived は Base の派生クラス
Base* pBase2;
// ★ここで、pBase2 にさっきnewしたインスタンスの複製をつくってそのアドレスを格納したいです。
std::mapで要素の部分にインスタンスを入れていました。
更新されるmapと、←を一時的にロックして複製して、複製にメソッドで操作を行おうと思っていました。
ポインタを要素の一部に含まないstd::mapのコピーを行うと、内容がそっくりうつるので、とても便利だなぁと。
既に気がついた方もいるかと思いますが、(継承の経験が無く、)誤って、ポインタではなく、基底クラス型を指定していました。
するとどうも、スライシングということが起きることに気がつきました。
基底クラスのメソッドしか呼べないし…。
そこで、ポインタに変更しようとしたら、要素の複製の方法がわからない、と。
以上、よろしくお願いします。
コピコン
659 :
657:2011/11/20(日) 22:00:47.11
いま、ふと思いついた方法は、全ての派生クラスを継承しているクラスを作成して、そこへダウンキャストな複製をした後に、そのポインタを、
…、
とか考えましたが、スマートではないですね。
そのクラスを作るという行為も異常ですね。
struct base {
virtual base * clone(void) const = 0;
};
struct derived : base {
derived * clone(void) const { return new derived(*this); }
};
661 :
657:2011/11/20(日) 22:15:31.04
回答がついてるから重箱の隅つつきしかできないんだけど
×Derrived
○Derived
663 :
657:2011/11/21(月) 08:33:43.17
>>662 おぉ!?、ありがとうございます。
どっかのサイトで見て、過去過去分詞はrふたつなのかぁ、ふーん、って思ってた。情けない。
664 :
657:2011/11/21(月) 08:46:22.71
>virtual base * clone(void) const = 0;
↑は、どういう意味です?
virtual base * clone(void) const { return new base(*this); };
のようにはしないのですか?
純粋仮想関数・・・・
基礎の基礎なんだが
int i1;
int* pi1;
int* pi2;
pi2 = &(*(pi1));
これって、pi1とpi2とで、指しているインスタンス違います?同じです?
Int()というのについて、リファレンス読むと答えわかります?
>>666 そもそもpi1が何も指していない状態でデリファレンスしているので鼻から悪魔。
668 :
666:2011/11/21(月) 10:25:45.18
int i1 = 10;
int* pi1 = &i1;
int* pi2;
pi2 = &(*(pi1));
std::cout << " pi1 : " << pi1 << std::endl;
std::cout << " pi2 : " << pi2 << std::endl;
忘れてた。
pi1とpi2が示しているアドレスそのものを表示させてみてから質問するべきだでした。
同じですね。違ったら質問する価値があったかもしれないが。残念。
失礼しました。
#include <iostream>
#include <map>
#include <string>
int main() {
class StringLap
{
public:
std::string hoge;
};
std::map<int, StringLap*> foo1;
}
上記をeclipseで行うと、コンパイルが通りません。どうしてでしょうか?
Visual C++だと通ります。
よろしくお願いします。
error: `main()::StringLap*' uses local type `main()::StringLap'
error: trying to instantiate `template<class _T1, class _T2> struct std::pair'
error: template argument 4 is invalid
error: invalid type in declaration before ';' token
>>669 eclipseでなくgcc(mingw-gcc?)のバージョンかコンパイルオプションのせい。
C++98/03ではローカルクラス(及びその合成型)はテンプレートの実引数にできない。
669です。
>>670 ありがとうございます。理解できました。
寿命の順番を保つのに
struct deleter { shared_ptr<x> p; void operator () (y * q) { delete q; } };
shared_ptr<x> p(new x);
shared_ptr<y> q(new y, deleter(p));
こういうこと普通にやりますかね?
もっと直接的に明確に寿命の順番を決めれるイディオムとかってありますか?
c++の内部クラスって、Javaと違って外側のクラスのフィールドに直接アクセスできないみたいなんですけど、
何か一言書くと出来るようになるおまじないとか無いのですか?
欲しかったら、内部クラスのインスタンスを生成する際に、外側のクラスのポインタを渡して参照させないとダメですか?
ダメです
>>672 書いた順とは逆順にデストラクタが呼ばれるから、そんな無意味なことはする必要がない
その一文がないと暗黙のコピーコンストラクタが生成される
その一文があると(継承元以外)何もしないコピーコンストラクタが生成される。
>>677,
>>678,
>>679 みなさん、ありがとうございます。
EffectiveC++は第二版と第三版とどっちがよいですか?
第三版は、意味が逆に取られそうな箇所があると○mazonのレビューに書いてありました。
最新の第三版を買えば、改修されているのでしょうか?
第三版は10年以上前なのであまり良くないのでしょうか?
ところで、コンストラクタについて、もうひとつ教えてください。
いま手元で継承先のインスタンスを作った際にどのようにコンストラクタが呼ばれるか実行して動作を確認してみているのですが、
継承先のコンストラクタを記述する際に、
継承元に引数なしのコンストラクタがある場合は、デフォルトでこのコンストラクタが呼ばれ、
継承元に引数なしのコンストラクタがない場合は、明示的にどのコンストラクタを利用するか指定しないとコンパイルエラーになる、
のですが、これは仕様ですか?特に前者。
いいとか、いやとかではなくて、そのように覚えてしまってよいのかな?と。
×第三版は10年以上前なのであまり良くないのでしょうか?
○第二版は10年以上前なのであまり良くないのでしょうか?
翻訳第三版と、原書か翻訳第二版を買えば対照できるので問題なかろう。
683 :
680:2011/11/21(月) 18:09:23.06
>翻訳第三版と、原書か翻訳第二版を買えば対照できるので問題なかろう。
了解した。
派生クラスで、コピーコンストラクタのオーバーライドを強要することは出来ます?
デストラクタのようにvirtualかなと思ったら、別の意味でした。
できません
685 :
デフォルトの名無しさん:2011/11/21(月) 19:27:09.15
C++初心者です。
struct Hoge {int foo,bar,baz}; という構造体があるとして、
これをstd::mapの値として使うには、どのように書けば良いでしょうか。 キーはとりあえずintとします。
std::map<int,Hoge> m;
……まではコンパイルが通るのですが、どうやって要素を追加すればいいのかが分かりません。
Hogeを配列にして、そのインデックスをmapに突っ込むという方法も考えましたが、
すごく無駄なことしているような気がします(´・ω・`)
m.insert(std::pair<int, Hoge>(123, Hoge()));
>>685 map<int, Hoge> m;
for(int i=0; i<10; i++) {
Hoge h = { 100+i, 200+i, 300+i };
//m[i] = h;
//m.insert(make_pair(i, h));
//m.insert(pair<int, Hoge>(i, h));
//m.insert(map<int, Hoge>::value_type(i, h));
}
>>685 struct Hoge {
int foo, bar, baz;
};
int main()
{
std::map<int, Hoge> mih;
const int N = 10;
for (int i(0); i < N; i++) {
Hoge h;
h.foo = std::rand();
h.bar = std::rand();
h.baz = std::rand();
mih[i] = h;
}
for (std::map<int, Hoge>::const_iterator pos = mih.begin(); pos != mih.end(); ++pos)
std::cout << "mih[" << pos->first << "] = (" << pos->second.foo << ", " << pos->second.bar << ", " << pos->second.baz << ')' << std::endl;
}
690 :
685:2011/11/21(月) 20:37:52.73
ありがとうございます!
>>686 初期値を指定しないなら、それが一番簡単そうですね。
コンストラクタを用意すれば初期化も出来そうですが、そうなると初期化子が使えなくなるという。
>>687 そこは読んでいたのですが、構造体を突っ込む方法が分かりませんでした(´・ω・`)
>688-689
初期化子や、構造体に代入する別の関数(SetHoge()的なもの)を流用しようと考えると、
素直にforで回すのが良さそうですね。
>>690 次はconstなmapをどうやって初期化するかで悩むね
エラー箇所は把握しているのですが、修正方法がどうしてもわからないので、助けていただけないでしょうか。
環境
Visual Studio 2010 Professional
DirectX SDK (June 2010)
コード
http://codepad.org/roAJTiEX メインループからは、Sequence::ParentクラスのUpdate関数が呼ばれています。
ここまでで実装しようとしていることは、シーンを切り替える処理と、シーンごとの描画を行う処理です。
Sequence\Childクラスを継承するTitleクラス、StageSelectクラスを
1キー:Title 2キー:StageSelectと切り替えるだけの処理を行なっていますが、
実行直後はTitle→2キーを押してStageSelectに切り替え→1キーを押してTitleに切り替えたところで、
エラー
game.exe の 0x779915ee でハンドルされていない例外が発生しました:
0xC0000005: 場所 0xfeeeff2e を読み込み中にアクセス違反が発生しました。
が発生してしまいます。
具体的にはTitleクラスのコンストラクタから呼ばれた、shader.setRenderState関数内の277行目ですとか、
277行目をコメントアウトした場合は281行目で起きてしまいます。
要するに2回目には初期化済みじゃないことになっている?みたいなのですが、なぜなのかわかりません。
コメントがなくてよみづらく、長いコードになっていて申し訳ありませんが、どうぞよろしくお願いします。
ごめんなさい、新規質問なのでageます
どこから例外が投げられてるのかすらわからない。
C0000005 は多分ぬるぽ系のアクセス違反
Titleが持ってるShaderがデストラクタで全部解放する作りになってる
void Parent::Update() {
Child* next = m_child->Update(this);
if (next != m_child){
SAFE_DELETE(m_child); <-- シーンが変わって delete m_child
class Title : public Child {
::myDirectX::Shader shader; <-- Title をdeleteしたらデストラクタが呼ばれる
Shader::~Shader(void) {
RELEASE(m_pd3dDevice);
m_dxDevice->Destruct(); <-- 関数呼んでる
void DXDevice::Destruct() {
if (--m_ref_count <= 0) {
SAFE_DELETE(m_instance); <-- m_instance は delete される
DXDevice* DXDevice::getInstance() {
if (m_instance) {
} else {
MessageBox( 0, _T("DXDeviceクラスの初期化をされる前に呼び出しがありました"), NULL, MB_OK);
PostQuitMessage(EXIT_FAILURE);
return 0; <--- NULL 返してる、これを使ってアクセスしてぬるぽ?
>>695 SUGEEEE!
270行目をコメントアウトすることで、無事通りました!
Shader::~Shader(void)
{
//RELEASE(m_pd3dDevice);
m_dxDevice->Destruct();
}
この行をShaderクラスが行ってしまうことによって、
まだ使うはずのDXDeviceクラスのm_pd3dDeviceが解放されてしまい(NULLポインタになってしまい)、
277行目から飛んだ562行目でNULLポインタ参照、
または、281行目でNULLポインタ参照がおきてしまっていたのが原因でした。
2,3日ここでつまっていたので、本当に助かりました!ありがとうございました!
698 :
697:2011/11/22(火) 20:32:28.78
>C0000005 は多分ぬるぽ系のアクセス違反
あ、あと、これは知りませんでした。
勉強になりました!ありがとうございました!
ぬるぽをがっする程度の能力の持ち主か・・・
~Base()がvirtualならばBase*から~Derrived()を呼び出すことができるのでやっていい
そうでないならだめ
702 :
700:2011/11/23(水) 02:06:35.86
継承してないけどね
704 :
700:2011/11/23(水) 03:00:15.17
>継承してないけどね
ほんとだ!継承してない!
何という節穴…。
ありがとうございます。
705 :
デフォルトの名無しさん:2011/11/23(水) 19:27:13.91
vc2010expressでの結果です
doubleの値をunsigned long longへキャストする時
LONGLONG_MAXを超えULONGLONG_MAX以下の数が
正しく変換されません(0x8000000000000000になる)
これってこのコンパイラだけですかね
Cの標準的にはどうなんだろう
他のコンパイラのでの結果を教えてください
コンパイラ依存するような巨大数は、多桁計算ライブラリつかう。
>>705 0x800・・になるのが正しいかは知らんが、
(unsigned long long int)double_manko; → llrint(double_manko) なのだから
unsigned long longの値を扱えないのは正しいのでは?
ISO/IEC 9899:1999 H.2.4
VC++9か10で、float演算中に0.0fで割った場合に
int演算の時のゼロ除算みたくデバッガ等で検出することってできますか?
operator=
の戻り値ってどうして参照なんですか?
構造体そのものが返ってる気がするのです。どう考えればよいのでしょう?
712 :
657:2011/11/23(水) 23:12:52.82
>>660 >struct base {
> virtual base * clone(void) const = 0;
>};
>
>struct derived : base {
> derived * clone(void) const { return new derived(*this); }
>};
これって純粋仮想関数のオーバーライドって言うのですか?(抽象クラスの実装とか?)
戻り値の型が、base* と derived* とで異なりますけど、その辺のところは気にしなくてOKです?
コンパイルは通って、目的の動きをしているのは確認済みなのですが、何となくしっくりこないす。
713 :
デフォルトの名無しさん:2011/11/24(木) 04:10:44.77
C++でCGIを作ろうとしているんだが、
複数行(マルチパート)の標準入力取得がうまくいかない。
fread、std::cin >> 変数等試してみたが、1行目しか取得できなかったり、
全く取得できなかったりする。
一括で(じゃなくてもいいけど)、複数行の標準入力を取得することはできない?
>>713 読み込みを行で止めないとすると、どこまで読みたいのか言ってもらわないと。
やりたいこと・実際にやったこと・実際の結果の3つを示すのが相談の基本だぜ。
>>712 > 戻り値の型が、base* と derived* とで異なりますけど、その辺のところは気にしなくてOKです?
仮想関数で共変の返却値を実現するために用意されてる機能。規格にあるのでその意味では気にしなくてよい。
716 :
デフォルトの名無しさん:2011/11/24(木) 20:10:15.34
VC++2010を使っています
範囲選択後にタブでまとめて右にインデントができますが、
左にインデントはシフトとタブで実現できました。
本当にありがとうございました。
それは知りませんでした
どうもありがとうございます
718 :
デフォルトの名無しさん:2011/11/24(木) 21:17:17.34
VC++2010、windowsXPという環境です。
hitoクラスのコンストラクタでokanクラスのメンバに影響を与える時、
「静的でないメンバー参照は特定のオブジェクトを基準とする相対参照である必要があります」
とエラーメッセージがでてコンパイルできません。
下のコードだと6行目 okan.hp-- の部分です
これはなぜでしょうか?
class hito
{
public:
int hp;
hito(){
okan.hp--;
}
};
class okan{
public:
int hp;
};
前近代的言語設計の上に建てられたC++の憂鬱ですね
ワンパスに物凄い拘りがあるのかワンパスの制約がなんか都合がいいのか知らんけど
>>718 各クラスのメンバ変数は、生成したインスタンスごとに別物として扱うから。
実際に生成されてない(もしくは指定されていない)のに、hpに1足しますって言われても、主語を言えよ!って怒られる。
721 :
デフォルトの名無しさん:2011/11/24(木) 21:37:51.05
>>720 クラス名とインスタンス名を間違えていました。大変申し訳ありませんでした。
逝ってきます・・・
ある派生クラスのオブジェクトを生成するとき、
基底クラスのコンストラクタを実行させる方法ってありますか?
ちなみに環境はVC++ 2010 Express Edition、OSはWindows VistaもしくはWindows Developer Preview です。
よくわからんが、普通実行されるかと
>>723 基底クラスの引数を取るコンストラクタを使いたいわけなのですが、
派生クラス(コンストラクタは定義していない)のオブジェクトを
引数を付けて生成してやると、コンパイルエラーが出るのです。
class Derived : public Base
{
public:
Derived(int a) : Base(a) {}
}
こういう事?
>>725 出来ました、ありがとうございました!
しかし何が起こっているのやらさっぱりなので説明してくださると有難いです。
初期化リスト内で基底クラスのコンストラクタを呼べる
初心者なんですが以下の現象ではまっております。
対策をご教授頂けます様お願いします。
■環境
言語:C
HW:SunFire V240
OS:Solaris9
コンパイラ:SunStudio付属(?) cc
下記のようなソースにて、構造体のメンバを増やすと、関数functionを
呼び出した際にセグメントエラーとなってしまう。※定義の直下にデバッグ文を入れても出ないため定義自体でアウトになっている?
dbxでcoreを読み込んでみると「フォルトのアドレスにマッピングしていません」等のメッセージ。
--------------------
typedef struct {
int ia;
short sa;
short sb
}child;
typedef struct {
child ca;
child cb;
child cc; // 新規追加
}parent;
int function() {
parent pa[288][140];
//以降処理
}
--------------------
730 :
デフォルトの名無しさん:2011/11/25(金) 01:18:24.63
>>729 100%勘で答えるけど、
その構造体の配列宣言のところでエラーになってると思う。
原因は配列全体のサイズが大きいから。
その宣言の仕方だとその配列に割り当てられるメモリ上のアドレスは連続していなければならないため、
例え容量が空いていても連続した領域でそれだけの領域が確保できなければエラーになる。
malloc使えば領域確保の段階でエラーが出てるかどうかをきっちり判別できるはず。(mallocの戻り値で判別)
どうしたら良いんだろうな、
parentの配列一つ一つにmallocで確保した領域を渡してやればいけるだろうけどそれはスマートじゃないしな。
教えてエロい人。
とりあえず、スタック領域の不足なのはほぼ確実だろ。
解決策はいくつかあるが、例えば
・コンパイラのオプションでスタック領域を増やす・・・場当たり的、コンパイラ次第では不可
・staticで宣言する・・・再起呼び出しや複数スレッドからの呼び出しができない
・動的に確保する・・・開放が必要、C++ならvectorの利用もあり
等々。
二次元配列であっても、mallocで確保するのは一次元のときと違いはない。
ただし、当然ながら最後の次元以外の要素数は、定数でなければいけない。
いまどき1メガ程度連続領域で取れると思っていいので、そこは考えなくていいと思うよ。
intが4byteの環境で、既に1Mぎりぎり。
ここに「メンバを増やすと」落ちると言っている。
だからスタックサイズだろ?
なにがなんだか意味不明なんですけど
>>729-731 二次元配列を動的確保する方法は何通りかあるが、
pa[a][b]のように書くことに拘らないならば
一次元として確保するのが拡張性からも保守性からもお勧め。
その場合、こんな感じ。
-- こういう関数を用意して
unsigned offsetOfPa(unsigned a, unsigned b, unsigned bSize) {return a * bSize + b;}
-- こうやって確保して、
parent * pa = malloc(sizeof(* pa) * 288 * 140);
-- こうやって使って、
pa[offsetOfPa(a, b, 140)];
-- こうやって解放する。
free(pa);
-- 面倒だったら関数を用意しないで毎回計算式を書いてもいいけどね。
vector<hoge> v(row * col);
auto at([&](int i, int j) -> hoge & { return v[i * col + j] ; });
at(4, 5).func();
いいなぁ、auto。
739 :
デフォルトの名無しさん:2011/11/25(金) 18:30:18.48
VisualStudioのスレでその話題見たばかりだぞ
ソースコード整形ツールつかえ。
IDEに限らず使える。
>>736 これでいいんじゃ
int function() {
typedef parent pa_140[140];
pa_140 *pa = malloc(sizeof(pa_140) * 288);
//なんか処理
pa[232][13].ca.ia = 1;
//開放
free(pa);
}
743 :
デフォルトの名無しさん:2011/11/25(金) 19:13:14.97
>>740 ナンテコッタ、偶然であります。マルチではないです。。
C-k C-f ですね、うまくいきました。ありがとうございました。
>>741 ありがとうございます
今後のためにも使ってみます
>>741 プロジェクトで決まっている整形ルールを設定する必要があるからなぁ。
大抵は一般的なスタイルだからいいんだろうけど、たまにね。
>>730 連続領域にするかどうかの話はさておき、mallocは確保できなくても確保できたように振舞う環境(設定)があるから気をつけてね。
>>747 これは知らなかった(; ゚д゚)いい勉強になりました。
EXEにDLLを含めるにはどうすれば良いですか?
リソースを調べてもDLLの入れ方が出てこないです。
Linuxのクソさ加減がまた露呈したな
こんなコトしてるからシェア奪えないんだよwww
>>729です。
>>730-
>>731のご両人はじめ、ご意見頂いた方ありがとうございました。
時間もないし、シングルスレッドゆえstaticつけて解決しました。
これからもちょくちょく質問させて頂きますので、よろしくお願いします。
Javaしかやってこなかったから厳しい・・・orz
インラインで速くなるとしたら、一カ所からしかコールされず、たいしたことをやっていない関数だ。
ソースへそのまま埋め込んでも良い所を、可読性のために関数化したときなど。
急にどしたの?
頭だいじょうぶ?
流石にどっかの誤爆だと思うけどなあ淫乱
展開されるから関数呼び出しのコストがなくなって
その分速いって事でしょ。
でもどんだけ速くなるのかのデータは見たことがないような...
今のCPUはほとんど投機実行とリターンバッファを持ってるから関数呼び出しにも
ほとんどコストが掛からなくなってるからな
リテラル文字列の寿命なんですけどプロセスが走ってる間は生きてると保証されてますか?
class MyExcept : public std::exception {
char const * m_pWhat;
MyExcept(char const * pWhat) : m_pWhat(pWhat) {}
char const * what() const { return m_pWhat; }
};
void func(void) {
throw MyExcept("something bad"); }
こう書いても問題は起こらないですか?
大丈夫だ問題ない
むしろ消えられたらこまる
c++でプログラムを書いていると、c言語の関数を呼ぶときに、名前空間がない「[なんもなし]::[関数名]」となるのに違和感を感じています。
後でソースを呼んだときに、this->なの?グローバルなの?と気にしたくなです、みたいな。(今はthis->を必ず書いています。)
c言語の関数を呼ぶときは、例えば「c::[関数名]」と出来るように何かをかぶせることは出来ないでしょうか?
実際に、今までどおりに呼ぶことが可能でもいいので、コードとして書くときにc::のような何名前空間の配下にいることを書きたいだけです。
例えば、DXライブラリがおもしろくて、最近使ってみているのですが、このライブラリ配下の関数を呼ぶときには、dxlib::[関数名]と書ければいいなぁなんて…。
よろしくお願いします。
712です。
レス遅くなりました。
>>715 >規格にあるのでその意味では気にしなくてよい。
了解です。ありがとうございます。
#define c
c::printf( "homu\n" );
設計書書いてみたいです。書いたことないです。見たこともないです。
C++でオブジェクト指向使ってます。
UMLっていいですか?現場で使ってますか?
設計書なんてどうでもいいからもっとコード書いた方がいいですか?
Effective C++のように、本当に役に立つようないい本はありますか?
質問は一つに絞るのがいいと思います
768 :
763:2011/11/26(土) 23:49:08.00
>>765 ?、!?、え?、あれ?
これどういう意味です?出来たのですが、理解できない。
…。
おぉ!、「#define c [なんもなし]」で、「c」がプリプロセッサに削除されるという感じですか?
間違ってたらレスよろしくお願いします。
(ヘッダ読んでみたら、DXライブラリが、C++で書かれていたので、既にDxLibという名前空間にあったのはさておき。)
>>763 namespace manko {
using ::GetTickCount;
using ::CreateFile;
}
>this->なの?グローバルなの?と気にしたくなです、みたいな。(今はthis->を必ず書いています。)
すまんが意味がわからん
>>768 なんもなしで
::printf ってやったのと同じだよ、thisの外にあるやつを明示的に使うときに使う
>>763 >dxlib::[関数名]と書ければいいなぁ
もちろん、DxLib.hを読んだ上で聞いてるんだよな?
>>765 #defineの痴漢マクロ使うバカはしね
>#defineの痴漢マクロ使うバカはしね
大きなアプリになると追えなくなるとか?
int cとか書くと酷いことになるな
>>775 コンパイルエラーで止まってくれるとは思うけど、
自分が書いたわけじゃなく、かつ見えるところに#defineが無ければ、そのまま丸1日くらい悩むかもしれんw
>int cとか書くと酷いことになるな
うわぁ…。
置換マクロ使ってるんだから当たり前のことだろ。プリプロセッサで処理するんだから。
何を今さら「置換マクロの危険性に気づいちゃった」的な驚きなの
namespace c {
#include <stdio.h>
}
これって大丈夫だっけ
リンクエラー
もうこれしかないな。まともに動くかどうかは知らん
namespace manko {
extern "C" {
#include <Windows.h>
}
}
int main() {
manko::GetTickCount();
}
>>782 できたとしても その中で定義されてるstructとかにキャストしたものを返すマクロを使うとキャスト部分にネームスペース入れられなくて詰む
どう考えてもラップする単位を間違えてる
とりあえず ::f これを見てグローバルかどうかわからん
>>763は出家した方がいい
>とりあえず ::f これを見てグローバルかどうかわからん
>>763は出家した方がいい
>>763は1行目と2行目との間でつながりがおかしな文章だが、そこから意味を汲み取れない
>>785は出家した方がいい
787 :
デフォルトの名無しさん:2011/11/27(日) 02:54:54.86
>>787 入力に与えられる「数」には負数もあるんじゃないの?
>>788 ありがとうございます!Accepted貰えました。
負数は無いものと勝手に思い込んでました…
Wikipediaのオブジェクト指向の項のコンストラクタ付近に
>「オブジェクトが入出力機器やファイルや通信、プロセスやスレッド、ウィンドウとウィジェットなど
>ハードウェアやオペレーティングシステム (OS) が提供する資源を管理するために利用される場合に、
>構築子や消滅子でそれらの資源の使用開始(オープン処理)や使用終了(クローズ処理)をそれぞれ管理し、
>通常のメソッドでそれらにまつわる各種サービスを提供するようにすることで、
>それらのリソースがあたかもプログラム中のオブジェクトであるかのように自然に取り扱うことができるようになる。」
と書いてあったのですが、コンストラクタで↑のような資源を取得することに失敗した場合ってどう対応すればいいのですか?
コンストラクタにはreturn falseのようなものがないですよね?
途中でthrowで例外を投げてしまう感じですか?
コンストラクタで例外は禁止
while(hoge = HogeClass()){
hoge.open();
hoge.read();
hoge.write();
hoge.close();
delete hoge;
}
>>790 そう。
コンストラクタで問題が起きたらコンストラクタから例外を投げるのが良くあるパターン。
javaのsuperみたいなものはc++にはありますか?
コンストラクタであれば、
class B : public A
{
public:
B() : A()
{
this->print();
}
protected:
void print()
{
std::cout << "piyoB" << std::endl;
// A::print(); と書くより、super::print();みたいな表記の方がわかりやすいかなぁ、なんて。
}
};
みたいに、継承元クラスのコンストラクタ名を指定すれば使えるみたいですけど。
よろしくお願いします。
795 :
794:2011/11/27(日) 10:59:03.37
まちがった。
×// A::print(); と書くより、super::print();みたいな表記の方がわかりやすいかなぁ、なんて。
○// A::print(); と書くより、super->print();みたいな表記の方がわかりやすいかなぁ、なんて。
typedefしれ
何に困ってるのかわからんな
Cの経験はあるのですが、C++は始めたばかりでCのfgets相当の事を、stdio.h,string.hを使わずにどうやるかで悩んでいます。
環境はgcc4,2,1です。
プロトタイプを自分で書いてfgets()を使うというのはなしか
class B : public A {
inline A * base() { return static_cast<A *>(this); }
public:
void f() { base()->g(); }
};
#include <iostream>
#include <string>
...
string s;
std::cin >> s;
804 :
794:2011/11/27(日) 11:36:35.34
>>800 おぉぅ!アップキャストとinlineで。なんか感動しました。
ありがとうございます。
(とりあえず、C++にはsuperは無いんですね。)
むしろC++の改良型&GC付加&多重継承無し&LLVMにしたのがJavaとC#だからな
いろいろとC++は古い
Cにいろいろくっつけて無理矢理OOP言語にしたのだから仕方がない
その代償として著しくCからの移行が楽になっている
806 :
794:2011/11/27(日) 11:45:30.39
794です。
もうひとつお願いします。
仮想関数の宣言のvirtualは、基底クラスのみに書けばよいのですか?
A→継承→B→継承→Cとしたときに、
該当のメソッドについて、全てのクラスにvirtualを書いた場合と、Aにのみ書いた場合とで、
A* pa = new C();
pa->method();
B* pb = new C();
pb->method();
した場合で、オーバーライドが効いているか試してみた感じそんな雰囲気でした。
基底のメソッドのみに書くのが正しいのかな?
807 :
794:2011/11/27(日) 11:46:53.33
×した場合で、オーバーライドが効いているか試してみた感じそんな雰囲気でした。
○した場合で、オーバーライドが効いているか試してみた感じ効いていました。
>>801,803
ありがとうございます!
Cとは作法が違う所が有るようですね。
もう少し勉強しなければ...
>>806 どっちでもいいが基底クラスには必ずvirtualが必要
§10.3.2
If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or
indirectly from Base, a member function vf with the same name and same parameter list as Base::vf is
declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides97)
Base::vf. For convenience we say that any virtual function overrides itself. Then in any well-formed
class, for each virtual function declared in that class or any of its direct or indirect base classes there is a
unique final overrider that overrides that function and every other overrider of that function. The rules for
member lookup (10.2) are used to determine the final overrider for a virtual function in the scope of a
derived class but ignoring names introduced by using-declarations.
>>804 端的に言うと、親が一人じゃないから特定できないんよ
>>806 仮想関数をオーバーライドする場合は仮想関数にすべき。
オーバーライドになるのか、隠蔽になるのかを知るために、
すべての親をたどらなければならなくなるため。
いま、Visual C++ 2010 Expressをつかって、C++のプログラムを書いたりしています。
ttp://codezine.jp/article/detail/125 ↑の「ステップ2 アダプタ一覧の取得」にあるような、ダイアログボックスを使いたいです。
サンプルプログラムを落として、2003→2010の変換をしてビルドすると、Expressでは無理、みないにいわれました。
@ダイアログボックスを出すには有料版が必要ですか?
AGUIとしえMessageBoxは使ったことがある(1行ですし。)のですが、ダイアログは数行では済まないでしょうか?
無理やりMessageBoxを繰り返してリスト的なことを実装したほうがらくなのかな、と意気消沈しています。
C言語でテキストファイルを読み込む際、空のファイルだった場合に強制終了をするにはどうすれば良いのでしょうか?
>>813 fp = fopen("test.txt")
if (fgets(buf, sizeof(buf), fp)) == NULL) {
exit(-1);
}
>>800 それは
>>794の望む結果にならないんでは。
C++なら this->A::print(); と書く。
>>816 「C++でSUPERっぽい書き方出来ないの?」が質問の主旨なんじゃねーの
VC限定なら__superあるけど
819 :
816:2011/11/28(月) 03:07:45.30
>>817 super経由で呼び出す関数を、派生クラスでなく基本クラスにしたいという意図と理解したんだが考えすぎ?
字面が似てるだけでいいならsuperって変数用意すればいい。
>>800のは動作がsuperと異なるぜ。
そもそも他重軽傷を許すC++にsuperなんて変だろ
なんのための static cast なんだろね
812です。
>Expressでも作れるけどわからない人からしたら苦行
>C#使えC#
HINSTANCE とか出てくると途端にコードの意味を読めなくなるので諦めます。
了解しました。C#を学んできます。
822 :
821:2011/11/28(月) 08:46:02.78
Boost C++ LibraryってC#で使えます?
C++じゃないから当然のように無理です?
無理
そんなのなくても.net frameworkは強力だから要らない
struct InterfaceA {
inline InterfaceA(A * p) : p(p) { }
inline void print() const { p->T::print(); }
A * p;
};
struct B : A {
InterfaceA base() { return this; }
void base_print() { base().print(); }
};
>>584です。質問の仕方がわるかったです。
もういちどお願いします。
たとえば、インスタンスが何個つくられたか記録してみよう、としたとき、
クラス変数を用いると比較的簡単に作れるかなと思いきや、
この方法では外から変数の値を書き換えが出来るので欠陥持ちです。
(確かJavaの入門書でこの用途の例題があった。)
クラスメソッドかインスタンスメソッドからのみ、書き換えを許可したいのですが、無理でしょうか?
#include <iostream>
class A{
public:
static int hogehoge; // 静的変数宣言
A() { this->hogehoge++; }
void printNum(){ std::cout << hogehoge << "個生まれたかも。" << std::endl; }
};
int A::hogehoge = 0; // 静的変数定義
class B : public A{
public:void printNum(){ std::cout << "ハンバーガー" << hogehoge << "個分かな。" << std::endl; }
};
int main()
{
A a1, a2;
B::hogehoge = 999; // protectedやprivateでは、static変数を宣言は出来るが定義ができない。
a1.printNum(); B b; b.printNum();
return 0;
}
って、なんかへんなことやろうとしてるな
> B::hogehoge = 999; // protectedやprivateでは、static変数を宣言は出来るが定義ができない。
これなんなの?コンストラクタでやるのはだめなの?
>>825 > int A::hogehoge = 0; // 静的変数定義
定義はできてるだろ。 private でも通る。
初期値が 999 なら 999 で定義しろよ。
privateでも定義できるだろ
830 :
825:2011/11/28(月) 18:07:09.52
> B::hogehoge = 999; // protectedやprivateでは、static変数を宣言は出来るが定義ができない。
↑は、出来て欲しくないことが、出来てしまうのでこまるなぁ、というつもりで書きました。すみません。
privateにするとコンパイル通りません、通りました。
あれー!?何度も試したんだけどな。
protectedで解決しました。
ありがとうございました。
クラスを継承するときに全部virtualで継承すればいいと思うんだけどどうなの?
>>831 無駄無駄無駄無駄無無駄無駄無駄無駄無無駄無駄無駄無駄
無駄無駄無駄無駄無無駄無駄無駄無駄無無駄無駄無駄無駄
無駄無駄無駄無駄無無駄無駄無駄無駄無無駄無駄無駄無駄
無駄無駄無駄無駄無無駄無駄無駄無駄無無駄無駄無駄無駄
無駄無駄無駄無駄無無駄無駄無駄無駄無無駄無駄無駄無駄
無駄無駄無駄無駄無無駄無駄無駄無駄無無駄無駄無駄無駄
無駄無駄無駄無駄無無駄無駄無駄無駄無無駄無駄無駄無駄
無駄無駄無駄無駄無無駄無駄無駄無駄無無駄無駄無駄無駄
無駄無駄無駄無駄無無駄無駄無駄無駄無無駄無駄無駄無駄
無駄無駄無駄無駄無無駄無駄無駄無駄無無駄無駄ァーー!
privateがいいの?
public が嫌なら、そうだろう。
boost::this_thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(1));
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
↑ふたつって、意味は同じ?
それとも、下側のソースは、基準になる現在時刻がないから、最低の時間のsleepになる?
テンプレートでどう変化するのか良くわからない。
よろしくおねがいします。
…boostスレに書いたほうがいいです?(過疎ってるみたいなのでこちらに書いてみました。)
p = XOR(!(a < b) && !(b > a), a == b)
これは常に真になるべき?
>>837 !(a < b) && !(b > a)
ここがバグってんじゃないの
>>837 分かりにくいので式を簡単にしていく。
p = XOR(!(a < b) && !(b > a), a == b) ・・・ 最初の式
p = XOR(!(a < b) && !(a < b), a == b) ・・・ aとbの向きを合わせる
p = XOR((a >= b) && (a >= b), a == b) ・・・ NOT取る
p = XOR(a >= b, a == b) ・・・ (a >= b) && (a >= b)をまとめる
ここで試しに値を入れる
a > b = 真
a == b = 偽
a < b = 偽
840 :
デフォルトの名無しさん:2011/11/30(水) 21:58:48.20
よろしくおねがいします
ある関数が、共有ライブラリの中で見つかったらそれを使い、
見つからなかったら静的な関数を「デフォルト」として使うようにしたいのですが、
どのようにしたらいいのでしょうか?
書いてあることをそのままコードにすればいいよ
842 :
デフォルトの名無しさん:2011/11/30(水) 22:15:22.76
言い忘れていました
共有ライブラリであるところの「ファイル自体」が存在しない場合も
まともに実行ファイルが起動するようにしたいです
素朴にやると、ビルド時に指定したファイル名の共有ライブラリがないと起動しないですよね
やりたいことを素直にコードにすればよい
起動時に自動で共有ライブラリのロード・リンクをさせるんじゃなくて
起動後に共有ライブラリを(あれば)ロード・そこから各関数の関数ポインタを取得して利用するようにする
LoadLibrary + GetProcAddress
おまいら優しいな
class Hogeのインスタンスをコンストラクトしようとしてたつもりが
コンストラクタ−を読んだだけだったというミスをしていた
//Hoge hoge(hikisu);//のつもりで
Hoge(hikisu);//と書いていた
目的の動作はしなかったけどコンパイルは通ってて、これはなにをしてるの?
単に関数として呼んでるだけ?
もろちん同じ事をやってるよ。つまりclass Hogeのインスタンスを
引数 hikisu でコンストラクトしている。
ただし、名前が無いのでアクセスできず、結果として文の終わりで破棄される。
破棄されるタイミングが文の終わりなのですか、不思議な感じ
しかしそれだとなるほど目的の動作にはならないわけだ
class CELL , class TISSUE , class ORGAN , class PENIS というクラスがあったとして、継承はこの順番でいいんですかね?
あと、class HUMAN はどういう構造にすればいいんでしょう?
class HUMAN
{
class LUNG
class HEART
といったように、各器官を包含するようにすればいいのか、
class HUMAN
{
class RESPIRATORY_SYSTEM
class REPRODUCTIVE_SYSTEM
のように系を中心としてまとめればいいんでしょうか? くだらない質問ですみません。皆さんならどうします?
どっちでもいいです
その時所属してるチームの方針によって変わります
>>851 レスありがとうございます。
個人やチームの、その時々の考え方で変わるということですね。
前者は、人間は複数の器官から成り立つという考え方、後者は機能(系)に注目した見方と思います。
どちらが良いか・優れているか、ではなく、場合により適切な方を選択すれば良いということでしょうか。
クラスについて、さらっと勉強した程度ですので、どのように設計すれば良いかが分からず、難しく思います。
クラスの設計に「正解」はないのかもしれませんが・・・
クラスを設計する時に、メンバ関数を仮想関数にした方がいい時って
どんな時ですか?
派生クラスのインスタンスを、基底クラスにキャストして、そこから派生クラス側で
オーバーライドした仮想関数を呼び出すような使い方って、あまり思いつかない
のですけど。全部、非仮想関数にするのは反則?
>>853 基底クラスのメンバ関数を、派生クラス側で実装してほしい場合
かつ
基底クラスを利用する既存のプログラムを、そのまま利用したい場合
なるほど・・・、分かりました(`・ω・´)
856 :
デフォルトの名無しさん:2011/12/03(土) 09:59:14.01
風よ,雲よ,太陽よ,心あらば教えてくれ・・・
g++のnewはいったい何時からデフォルトではNULLを返さなくなったのだ・・・
いやそうじゃねえ
バージョンとか年とか
クラスをpublic継承して、そのクラスの一部のメンバ関数を継承先のクラスでprivate化させることは可能ですか?
基底のクラスはそれ自体で使うことがあるのでprotectにするのは無しで
Yes, we can.
そういう用途にはpublic継承は使わない
public継承は「派生クラスなら基底クラスである」という条件を満たす場合に使うもの
一部分でもprivate化してしまえばそのルールが崩れてしまう
そういう時にはprivate継承して公開するものだけをpublic化するか、
継承させずにメンバ変数で持たせてディスパッチするメンバ関数を用意する
思想が逆なのね
private継承して公開するものをpublic化てどうするの?
へー
usingてこういうふうにも使えるのか
ありがとう、勉強になった
まだ何も始めていない初心者以下の者ですが
今一番一般的なC(参考書やサイトで情報が多い)はなんというものでしょうか
C#は避けたいです。
今インストールされている開発ツール(マイクロソフトのVB.NETやC#が入っているもの)では
.NET、MFC、Win32あたりでフォームアプリが作れそうなのですがどれが良いでしょうか?
C#やれ
ちょっとしたツールのWindows フォームアプリを作るならC#一択
プロの現場でもそうやってよく使われています
VB.NETから移行しようと思ってるのですが
C#だとあまりメリットがない気がしますが・・・
C/C++のほうがメリットねーよ
おとなしくC#やれ
VB.NETから移行しようと思った理由がわからないし
C#にしておけとしかいいようがない
言語の選び方は何を作りたいのかによって変わってくるので、
まずそれを伝えないと
ウィンドウとかOSよりの仕事をC#に任せてゲームロジックと描画をC++とDirectXで、みたいな感じで融合させることって出来るんですか?
C++からC#同等の機能を使えるだろ。分けて使う必要なし。
>>875 そうやって初心者だますのやめろよ本当に
騙したつもりはないが。記述の困難具合は別にしてC#、VBでできる事はC++/CLIで可能だろ。
C++/CLI最強!
と思っていた時期が僕にもありましたが、
マイクロソフトの営業さんに、おすすめしません、と言われてしまった...
C++とC++/CLIは別物だからな
C++って書いたら騙してるも一緒だろう
>>872 VB.NETから移行したい理由は逆アセンブルでコードが可視化するのがいやなのと
処理速度が速いのと、なんとなくプロっぽいのでやってみたいなと・・・
じゃあMFCでもやってろ
たぶん挫折するだろうが
そんなやつがCとかやったら発狂してファックファック言いまくるに決まってる
C++/CLI は 2008 -> 2010 と順調に退化してるからな
オークションのシミュレーションプログラムを作りたいのですが、これってエクセルでもできますか?
できるだけ簡単に作りたいです
そこまで本格的なものではなく、単純なものでいいなですが
何かアドバイスをお願いしまさ
エクセルのスレで聞けば?
何も始めていない初心者以下の者がVB.netから他の言語に移植しようとしているということだよね。
ええと、へんな話になると思うけど、まずはVB.netをやってみるのがいいと思うよ。
Cは使うことができます
しかし、一体なにから始めればいいのか.......
シミュレーション作成ならfortranの方がいいんですかね
890 :
889 :2011/12/04(日) 03:39:55.74
あ、C/C++の掲示板だったと忘れてた
>>889は無視してください
enumって安全にintに変換できますか?
っていうかenumを安全に変換できる整数型ってあります?
安全にとは?
危険じゃなく。
サイズが足りなくて上位ビットが切り捨てられたりしないか、ということです
intに入れる分には大丈夫
intそのものだっけ?
enum foo : long long{bar = LLONG_MAX};
C++11ではそのような甘えは許されない
なんでnewしたものをdeleteしてもNULLになんないの〜
ま、いまさらどーでもいいけど
めんどくさかったんでしょう
ゼロで上書きするコストが無駄だったから
C系列はそういう下らないことにこだわる言語なんだよ
deleteは左辺値だけじゃなく右辺値もとれるから
void func(void);
&(func);
はできるのに
struct hoge { void method(void); }
&(hoge::method);
はできないのはなんで?
実体が無いから。
いえ、括弧をつけるとなぜかできなくなるんです
普通の関数はカッコを付けてもおkなのに
>>901 へぇ。
delete hoge = new Hoge();
とか?
普通の関数なら、(func)と書いても関数そのものと解釈されるけど、
(hoge::method)の時点で、staticメンバ関数呼び出しと解釈されて、演算子()が続いてないからエラーになるんじゃないかな?
>>906 ∧_∧
( ゚ω゚ ) delete hoge = new Hoge();
C□と)
/ |
(ノ ̄`J
∧_∧
( ゚ω゚ )
C□l丶l丶
/ ( ) やめて!
(ノ ̄と、 i
しーJ
char *p = new char[...];
p += 4; //作業領域
...
delete p - 4;
みたいな。
この場合に限れば、単にp-=4の後にdeleteすれば同じだけど。
下のmain.hとmain.cppで、最後のがエラーになるのは何故ですか?
/* main.h */
class Person{
public:
std::string person_name;
int age;
};
class Group{
public:
std::string group_name;
Person *person;
};
/* main.cpp */
void GroupInitialize(Group *g){
Group *g1=new Group[2];
g1[0].group_name="group1";
g1[1].group_name="group2";
Person p1[2]={"hoge1",20,"hoge2",21};
Person p2[2]={"hoge3",22,"hoge4",23};
g1[0].person=p1;
g1[1].person=p2;
*g=g1[0]; ++g; *g=g1[1];
}
int main(int argc, char *argv[]){
Group *g=new Group[2];
GroupInitialize(g);
std::cout << g[1].group_name <<std::endl; //問題ない
std::cout << g[1].person[0].age <<std::endl; //問題ない
std::cout << g[1].person[0].person_name <<std::endl; //エラー
}
p1,p2がautoだから
GroupInitializeを抜けた時点でg[1].persoは無効なアドレスを指してる
>>864の10行目と11行目って、本来の意味もおなじなのですか?
と質問しようとして、
10行目の書き方だと、フィールド部分もpublicできるのか?
と思って、試したらその通りで、
両方の書き方があるって、覚えるだけでいいですか?
本来の意味的な意味で。
全然違う意味です
array<String^>^ a = gcnew array<Sting^>(10);
これをdeleteするには?
delete[] a;
delete a;
どっち?
後の方
c++ cliではarrayを使ったら[]はいらないのね
ありがとう
c++でもそうだけど。
要るわけ無いじゃん
>>919 std::vector<int> *p = new std::vector<int>();
delete p;
いらない。[]をつけるのは[]がついてるときだけ。
922 :
919:2011/12/07(水) 16:52:17.93
あ、そうゆうことね。
「配列っぽく使える」であって配列そのものではないと勝手に認識している
そういうことねとすんなり理解できるなら
>>915のような疑問は出てこないはずだが、、、別の人か。
te
他人の作ったクラスをシリアライズするにはどうすればいいですか?
自分が作ったのと同じ
でもプライベート領域にアクセス出来ませんよね
friend
クラス宣言は書き換えられないんですよ
他人にお願いする
その型と同じメモリ配置の型を定義してポインタ経由で無理やりキャスト
ではインターフェースクラスだった場合はどうすれば?
アップキャストされた状態でやりたいっていう話なら無理じゃね
そうですか残念です
シリアライズする予定のクラスには一部のライブラリは使えないということですね
そらそうよ
VC++2010で勉強し始めたのですが変数の代入の値がおかしくなってしまいます
自動変数という項目は正しい値が出ているのにコンソールになると
「1837536996たす30193049は2147328000」となってしまいます
何が悪いかも分からず困っています
何が原因なんでしょうか?
#include <stdio.h>
int main()
{
int a, b, c;
a = 10;
b = 15;
c = a + b;
printf("%dたす%dは%dです\n"), a, b, c;
return 0;
}
志村ー括弧!括弧!
あ・・・
分かりました。ありがとうございます!
恥ずかしい・・・
文法的には通る書き方だしなw
× printf("%dたす%dは%dです\n"), a, b, c;
○ printf("%dたす%dは%dです\n", a, b, c);
941 :
937:2011/12/08(木) 20:49:10.96
1日悩んだのに・・・
ま、まあとにかく出来たのでよかったです
ありがとうございました!
>>941 1日無駄にしないように、警告レベルを上げておくとよいのだよ。
>>942 gcc は printf のフォーマット文字列で要求した引数数と、実際に引数に渡してる数の差をチェックできるんだっけ?
VC は最近のは知らないけど、古いのではチェックできない(警告出せない)
iostreamを使っていればこんな事にはならなかったのにね
>>943 ほんとだ。てっきりclでもできるだろうと思い込んでたごめん
Visual C++ 2010 Express @ WindowsXP SP3
libxml2というライブラリをつかうことにしました。
すると、iconvとzlibも必要だ、と配布サイトに書いていたので準備しました。
とりあえず、libxml2のヘッダにパスを通してビルドすると、libがないと言われたので、libにパスを通しました。
次は、iconvのヘッダがない、といわれていたので、パスを通しました。
するとビルドに成功して実行可能な状態になりました。
実行時には、libxml2.dll・iconv.dll・zlib1.dllがないと言われたので、パスを通しました。
すると動きました。
そこで疑問が起こりました。
zlibのヘッダ使ってないのに、どうして、zlib1.dllが必要と言い出すのでしょうか?
ご存知の方教えてください。
(libxml2.dllかiconv.dllがzlib1.dllをよこせといっている?)
こんばんは、お世話になります。一件お願いします。
class Hoge{
public:
void foo(void){
std::cout << "foo" << std::endl;
this->piyo();
}
private:
void piyo(void){
std::cout << "piyo" << std::endl;
}
}
int main ()
{
Hoge hoge;
hoge.foo();
} //
ttp://codepad.org/aKOWeYt4 この中の、「private:void piyo(void)」をユニットテストしたい場合は、どうすればよいのでしょうか?
言語的には出来なくて、IDEの機能を使ったりする感じなのでしょうか?
class Hoge {
friend void Test(void);
};
eclipseのc++で、boostを使いたくて、自分でビルドして使ってみたらつかえました。
他の人のWebページでの紹介の通りにやったので、出来て当然なのですが。
WindowsとLinuxとか他のOSとで、同じソースというのが不思議です。
徹底的に環境に依存しないコードで書いているということなのでしょうか?
APIを使う場合は、どうしても環境依存になってしまう気がします。
どうしても依存しそうなときには、各OS毎にプリプロセッサで変化させるような書き方をしていて、未対応OSでは失敗してしまう感じですか?
>>949 OS差を吸収している。コンパイル可能な言語・OSでも全機能がおなじように使える訳でない。
どっかに公式の対応表がある。
はい
公式の対応表…?
アスタリスクを下のように出力するプログラムの作成の仕方を教えて下さい。
お願いします。
*
**
***
****
*****
******
*******
********
*********
**********
#include <stdio.h>
int main(void) {
puts("*\n**\n***\n****\n*****\n******\n*******\n********\n*********\n**********\n");
return 0;
}
最後に空行がついているのはどういうことでしょうか
>>955 書き忘れましたすみません。
if文を使った書き方を教えて下さい。
#include <stdio.h>
int main(void) {
if(1) {
puts("*\n**\n***\n****\n*****\n******\n*******\n********\n*********\n**********\n");
}
return 0;
}
どこにif文を使うのか想像できん
int n = 10;
for (int i = 0; i < 10; ++i) {
for (int j = 0; j < 10; ++j) {
if (i >= j) putchar('*');
}
putchar('\n');
}
nいらなかった(もしくは、ループ内の10をnに)
#include <stdio.h>
int main()
{
int i, j;
for( j = i = 0; i < 10; j=++i) while( j ? putchar( '*') : puts( "*"), j--);
return 0;
}
#include <stdio.h>
int main()
{
char s[]="**********";
int n=10;
while(n--)printf("%s¥n",&s[n]);
return 0;
}
for (i = 0; i < 10; ++i) {
if (i > 0) printf("*");
if (i > 1) printf("*");
if (i > 2) printf("*");
if (i > 3) printf("*");
...
printf("*\n");
}
#include <stdio.h>
int main()
{
char s[10]= {};
int i;
for(i=0; i<sizeof(s); i++) {
s[i]='*';
printf("%s¥n",s);
}
return 0;
}
>>958 やはり最後に空行がつきます。なにか意図があるのでしょうか?
>>965 > char s[10]= {};
これってどう定義されてたか覚えてないな。
未定義でいいのかな。
>>967 clangとgccではワーニングだね。
clang version 1.5
: warning: data argument not used by format string
gcc version 4.2.1
:warning: ISO C forbids empty initializer braces
良い子は真似してはいけない。
#include <stdio.h>
int
main()
{
char s[10] = {};
int i = 0;
while (1 - i / 10)
printf("%s¥n", s, s[i++] = '*');
return 0;
}
char s[]={"**********\n"};
int i=sizeof(s)-1;
do{puts(&s[--i]);}while(i);
while()の中で変数宣言した場合は、ループが回るごとに新しいスタック領域を確保するんですか?
それとも、ずっと同じ領域を使用するんですか?
>>972 973に補足すると、規格上はどちらとも決まっていない。
VC++やGCCでは同じ領域になる。
わざわざ領域を確保し直す理由もないから、他のコンパイラでも同じだと思うけど。
だなあ
わざわざEBPやRBPをいじって新しく確保すると速度が落ちるだけだし
977 :
デフォルトの名無しさん:2011/12/11(日) 19:07:37.19
ものの本に、「ヘッダはソースファイルのほうでincludeすべき」などと書いてあったからだろう
class定義のcppファイルの先頭に先祖代々のclassメンバ宣言ファイルがincludeされていた
・・・・どう思う? というか、どうすべき?
使おうとするクラスのヘッダファイルをインクルードすれば使える状態にすべきでしょ。
ですよねー
子クラス.h
------------------------------
#include "親クラス.h"
class 子クラス : public 親クラス {
・・・
};
--------------------------------
子クラス.cpp
------------------------------
#include "子クラス.h"
・・・
-----------------------------
そうとも言えないのがC++の難しい所なのだ。
例えば、ヘッダ内では前方宣言だけで済む場合は
インクルードすべきではない…コンパイル時間が爆発するからだ。
子クラス.h
class 親クラス; // 前方宣言で済むのでインクルードしない
子クラス.cpp
#inlcude "子クラス.h"
#include "親クラス.h" // 親クラスの実体サイズを知るためにインクルードが必要
えーっと、めんどいから参照しないけど、C++ Cording Standardsに書いてあったはず^^;
って考えてみたら、親クラスを継承するには親クラスのサイズが必要だから
前方宣言は無理だな。わはは。すまん。(´・ω・`)
質問者ではないけど、
関連性の強いクラス郡を↓のような感じでincludeしてるんだが、
これもなんだか気持ち悪いか…?
まとめ用ヘッダ.h
#include クラスAとクラスBとクラスCで使うヘッダ
#include "クラスA.h"
#include "クラスB.h"
#include "クラスC.h"
クラスA.cpp
#include "まとめ用ヘッダ.h"
クラスB.cpp
#include "まとめ用ヘッダ.h"
クラスC.cpp
#include "まとめ用ヘッダ.h"
例えば、クラスCが不要になって削除する時、面倒じゃないか?
普通に
(クラスA.cpp)
#include "クラスB.h"
#include "クラスC.h"
ってしちゃうな
A.cppでB.hやC.hが必要ないときの話だと思ったけど違うの?
c++での質問です。
void func(x){
//xの内容を表示
}
int a[10];
string s[20];
func(a);
func(s);
の様にしたいのですが、c++では難しいのでしょうか?
オーバーロードかテンプレート
#include <string>
#include <iostream>
#include <boost/range.hpp>
template<typename Range>
void print( Range& r )
{
using namespace boost;
typename
range_const_iterator<Range>::type i = begin(r), e = end(r);
for(; i!=e; ++i)
std::cout << *i << std::endl;
}
int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
std::string s[7] = { "a1", "a2", "a3", "b4", "b5", "b6", "c7" };
print(a);
print(s);
}
template <typename T, std::size_t N>
void println(const T (&a)[N])
{
std::cout << "{";
std::copy(a, a + N - 1, std::ostream_iterator<T>(std::cout, ", "));
std::cout << a[N - 1] << "}" << std::endl;
}
うめ
次スレ立つ前に「うめ」って……
C言語なら俺に聞け(入門編)
C++相談室
スレを勃てるまでもないC/C++の質問はここで
同じようなスレが多すぎる。
初心者はどこに書いたらいいのかわからないし
たいていの回答者はどのスレも見てる。
このスレは終了
あー、それもそうやね。
環境依存OKってのは、とても頼りになる一言ではないかい?