スレを勃てるまでもないC/C++の質問はここで 11
いつだったかお前のポニーテールは反則的なまでに似合ってたぞ
3 :
デフォルトの名無しさん :2009/06/15(月) 20:48:32
刀、 , ヘ
/´ ̄`ヽ /: : : \_____/: : : : ヽ、
,. -‐┴─‐- <^ヽ、: : : : : : : : : : : : : : : : : : : : : : }
/: : : : : : : : : : : : : :`.ヽl____: : : : : : : : : : : : : : : : : : /
,. -──「`: : : : : : : : : :ヽ: : : : : : : : :\ `ヽ ̄ ̄ ̄ フ: : : : :/
/: :.,.-ァ: : : |: : : : : : : : : :\: : : : :: : : :ヽ \ /: : : :/
 ̄ ̄/: : : : ヽ: : : . . . . . . . . . . .、 \=--: : : :.i / /: : : : :/
/: : ∧: \: : : : : : : : : : ヽ: :\: : : 〃}/ /: : : : :/ 、
. /: : / . : : :! ヽ: : l\_\/: : : : :\: ヽ彡: : | /: : : : :/ |\
/: : ィ: : : : :.i: : | \!___/ ヽ:: : : : : : :\|:.:.:.:/:! ,': : : : / |: : \
/ / !: : : : :.ト‐|- ヽ \: : : : : l::::__:' :/ i: : : : :{ |: : : :.ヽ
l/ |: : :!: : .l: :| \: : : l´r. Y {: : : : :丶_______.ノ: : : : : :}
l: : :l: : :ト、| 、___,ィ ヽ: :| ゝ ノ '.: : : : : : : : : : : : : : : : : : : : : : /
|: : :ト、: |: :ヽ ___,彡 ´ ̄´ ヽl-‐' \: : : : : : : : : : : : : : : : : : イ
!: :从ヽ!ヽ.ハ=≠' , ///// ///u /  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
V ヽ| }/// r‐'⌒ヽ イ〉、
ヽ、______ー‐‐' ィ´ /:/:7rt‐---、 こ、これは
>>1 乙じゃなくて
ィ幵ノ ./:/:./:.! !: : : : :!`ヽ ポニーテールなんだから
r‐'T¨「 |: | !:.∨:/:./: :| |: : : : .l: : : :\ 変な勘違いしないでよね!
/: : .|: :| !:.!ィ¨¨ヾ、:.:/ !: : : : l: : : : : :.\
会社出勤日数が減って 給料がアップするプログラムってないでしょうか?
>>4 俺も欲しいよそんなもん。
・・・あれだな、最高に便利なライブラリを作って
クローズドソースにして販売すること。
働かなくても金が入る。
6 :
デフォルトの名無しさん :2009/06/15(月) 23:15:09
7 :
6 :2009/06/15(月) 23:19:42
>>3 そのポニーテール、壊滅的なまでに似合ってないな。
アフィなら仕事しなくても儲かるのに
12 :
デフォルトの名無しさん :2009/06/17(水) 02:56:57
C++って、フィールド名とメソッド名同じにできないの? private: bool isComplete; public: bool isComplete(); ってやるとエラー吐かれるんだけど・・・
できないよ
「'」文字列にこの文字があるときだけ特別な操作をしたいのですが for(i=0;i<20;i++){ if(mozi[i]==''') } とやる訳にはいきませんよね?この場合どのような書き方をすればいいんでしょうか?
'\'' エスケープしろ
>>15 解決しました。
ありがとうございました。
フィールドとかメソッドとか、そんな呼び名はC++にはないっすよ。 どれもこれもメンバです。
BMPファイルを読み込むため char*ではなく char buf[100][100][3];みたいな配列に ifstreamを使ってバイナリ読み込みたい場合 どうするのが普通なのでしょうか とりあえずchar*に読み込んでコピーだとコストがかかってしまいますし ifs.read(buf,3)などとやると、型エラーが出てしまいます
ifs.read(reinterpret_cast<char*>(buf), sizeof(buf));
ありがとうございます。うまく行きました reinterpret_castってこう使うんですね
エンディアンの関係でRGBのうちBとRが逆転していたようなので 修正してみたのですが、書法的には問題ないですよね? 一応動作はしています for(int i=0;i<TEXHEIGHT;++i){ for(int j=0;j<TEXWIDTH;++j){ ifs.read(reinterpret_cast<char*>(texture[i][j])+2,1); ifs.read(reinterpret_cast<char*>(texture[i][j])+1,1); ifs.read(reinterpret_cast<char*>(texture[i][j]),1); } }
tr1::shared_ptrで配列を確保って無理ぽ?
23 :
12 :2009/06/17(水) 21:33:31
>>13 , 17
なるほど、どっちもメンバだから同じ名前にできないのかな?
ありがとう。
ifs.read(reinterpret_cast<char*>(texture[i][j])+2,1); これってキャストなしで動かない?
>>22 tr1::shared_arrayってあるっしょ?
ぐお・・・tr1::shared_arrayはないな boost::shared_arrayを使うしかない
>>24 ifs.read(texture[i][j],1);の時点でコンパイル通らないです
>>27 なんてエラー出るの?
> char buf[100][100][3];みたいな配列
これは texture ではないということ?
>>28 おっと、失礼しました
charにするとコンパイル通るし普通に動作もしますね
エラーメッセージ
GLubyte [3]' から 'char *' に変換できません。
「みたいな」、と書いてるのは
結局の所
typedef GLubyte char
となっているからです(openglのコードです)
typedef mychar char;として
mycharを使ったコードに書き直してもやはり同様のエラーがでます
これはちょっと勉強になりましたが、
しかし、どういうことなのだろう?
私の認識では、Cのtypedefは新しい型は導入しなくて MC++とかでは新しい型を導入するために struct{}でくくったものをtypedefで使っていたように思うのですが 認識違いだったのかなぁ・・
すみません、私の勘違い typedef unsigned char GLubyte; とtypedefされていてエラーになっていたみたいです
ああ、なら納得です。 unsigned char から char へのキャストは強制的に行うしかないですね。
C++初心者です。 ドット演算子とアロー演算子って、何で区別されてるんでしょうか? 変数とポインタで用いる場所が違うのは分かるんですが、どっちかに統一されてた方が簡便なような・・・ 可読性向上のためでしょうか? 何か他に理由があるなら教えてください。
>>33 可読性向上のためでしょ。
hoge->piyo->fuga->m_func()
なんて式があったとして、これを.演算子で書き換えてごらん?
hoge->piyo->fuga->m_func() と hoge.piyo.fuga.m_func() が等価であればよかったのにという話じゃないの? そうじゃないからこう書かざるを得ないだけで。 (*(*(*hoge).piyo).fuga).m_func()
両方.にしたらポインタそのものに演算してるのかポインタの示す先に演算してるのかどっちなのって気分になるから
hoge->piyo.fuga->m_func() と書かれていて、ああ、fugaはポインタなんだな、piyoは非ポインタなんだな、ということがわかることの メリットが見出せなければ、実質的に可読性が高まったとは言いにくい。 俺も同じならよかったのに、ということで参照渡しはよいよね。 C#のrefはさらによいよね。
オーバーヘッド削減だけならいいけど、値返し目的の参照渡しは好きになれないなぁ
>>37 横やりだが、C++Builderでプログラム書いてるとそういう->の
連続なんてしょっちゅう出てくる
あまりに長くてウザいので、with文を持たないC++なので途中までを
ポインタに保存しておき、そこから->を伸ばしてる
>>38 それも含めて、また、呼び出し側から変更されるかどうかが明確であるという点でC#はよいよね、に
つなげてたけどはしょりすぎたね。ごめん。
標準C++で質問させてください。 アルファベットの文字は必ずしも'a'-'z'まで連続してならんでいないと聞きました。 すなわちchに文字が入っているとして if('a'<ch && ch<'z'){******} では必ずしも全ての小文字を捉えられる訳ではなく、環境依存であると聞きました。 ですが数字は並んでいることは保証されていますか? すなわちchに文字が入っているとして if('0'<ch && ch<'9'){******} では必ず全ての数字を捉えられますか? 「捉えられない環境なんて見たことない」かどうかではなく、 標準C++で厳密に保証されているかどうかという視点で、 どうかよろしくお願いします。
>>41 そういう意味なら'0'〜'9'まで連続で並んでいるコードだという
保証は規格票には一切ない
isdigit()を使え
>>33 昔のCで区別されていたから。
なんでCで区別されていたかというと、昔はコンパイラがそんなに頭がよくなかったから。
p->mは、(*p).m と同じものに機械的に変換されていた。
それだけ。
>>42 数字はされているだろ。
何が一切無いだよw
>>41 is系の関数は並びがどうであれうまく動作することが保障されている
47 :
41 :2009/06/17(水) 23:39:13
みなさんありがとうございます。 isdigit()という便利な代物があることをご指摘いただきましたが 仕様上気になっていましたもので。
従来型の iostream ライブラリ
ttp://docs.sun.com/source/806-4840/Iostream.html ここに
>入力データの先読み
>メンバー関数 peek を使用するとストリームから次の文字を抽出することなく、
>その文字を知ることができます。
>使用例を次に示します。
>if (cin.peek() != c) return 0;
とありますが、それでは次の次の文字や次の次の次の文字や次の次の次の次の文字が
知りたい時はどうにかして知ることはできますか?
>>42 を擁護するつもりはないが、
>>45 ,45は規格のどのセクションか示してから発言した方がいいよ。
ここが規格準拠スレでなくてよかったね。C++の規格書を読むのは嫌だけど。
>>41 可読性向上も考えて、is*()使え。
規格票のどこに書いてあるか素直に尋ねればいいのにね。
54 :
50 :2009/06/17(水) 23:47:23
・・・数字の話ね、もちろん。
X3014:2003
2.2 文字集合
3 …… 上で掲げた表の0以降のそれぞれの数字に対応する文字の値は,
それの直前にある文字の値より1だけ大きくなければならない。……
>>48 tellg/seekgで読み取り位置を元に戻しておけばいい。
56 :
48 :2009/06/17(水) 23:58:12
>>52 自己レス
ISO/IEC 14882:2003(E) 2.2.3 3 In both the source and execution basic character sets,
the value of each character after 0 in theabove list of decimal digits shall be
one greater than the value of the previous.
ほらね
んー? C++の規格で「0-9は並んでなきゃダメ!」といっているのは、 そういう文字コードでしか正しく動きませんよって言っているだけなのでは?
は?当然だろ。何言ってるんだ
コピー代入演算子の返り値がtype&なのはなんで? (a = b) = cみたいな変なことができないconst type&のほうがいいと思うんですが
いいところに気づきました! そんなときのためにも C++ Coding Standards を読みましょう。 端的にいうと、STLコンテナに入らなくなります。
>>60 当然だったのか。
じゃあisdigitを使うべきかどうかなんて議論する余地もないね
小数点以下の桁が多いdouble型をToStringすると指数表記の文字列になっちゃうんだけど ToString(#とか0)で桁数制限せずに普通の表記にする方法はない?
>アルファベットが並んでる 実際のところ、普通のパソコン向けの開発なら 歩調されてないということさえ覚えておけば、あんまり気にしなくてOKなのかしら?
Your left! Your left! Left, right, left!
>>64 ToString…だと?
C#だろうねぇ
C#は+が4つもついてるんだから、C++よりも高級だろ。
何を唐突に?
恋は突然に
>>65 つか、アルファベットが隙間なく並んでいないと困るような状況ってあんまりないしな。
>>71 ゲーム系だと結構あるかも。
専用のグラフィックを用意して描画しなきゃならないことも多いし。
それはアルファベットのグラフィックがアルファベット順に並んでるかどうかの話でしょ
ん? 何か引っかかる?
vc++のGUI使ってるんだけどビルドオプションの設定とかがよくわからない makefileとやらも使い方を覚えてそっちを使ったほうがいいのかな?
デフォのままにしとけば?
関数の中で同じようなコードが連発するときって #defineを書いてまとめてもいいんだよね? #defineはグローバルスコープ以外にも書いてもいいんだよね?
#defineってスコープ認識したっけ?
そういやスコープ認識しなかったな。 ということは スコープに閉じ込めることはできない =>グローバルスコープ以外にも書いてもいい ってことか。 サンクス。
知りません。スコープはコンパイラの仕事なので、 プリプロセッサを担当するリンカは知ったこっちゃないからです。 逆に言えば、ソースのどこに書いてもOK
リロードしたらもう書いてあった・_・マムコ
コンパイル時に決まる文字列リテラル(const char*)の文字数を取得するマクロってない? つまり "hoge" "hogepiyo" "jder208o1ulk34paa16u9ky7gj7nfezb2yjshhpo6v28o90q8hyq67d3m42eq814gp6" の3つがあったとして、 これらの文字数をエディタで数えるとかじゃなく 取得する方法はない?
83 :
79 :2009/06/18(木) 21:43:08
sizeof("hoge")とかだめだったかな。
いまやったら、'\000'が入るから'\000'文字分を引かないといけない。 けど、ワイド文字とか多バイトのとき即死フラグが立っている。
文字列の最後は必ず'\0'で終わるから、メモリを調べれば長さがわかるよ。 変数の中に入っているならstrlenとか使えるし。 そういう意味ではなく?
あぁ、マクロか。よく読んでなかったよ、おっかさん。
88 :
82 :2009/06/18(木) 21:53:57
みんなありがとう。 コンパイル時に定数として文字数を取得したいんだよね。 それを用いて配列を定義したりするつもりだから。 sizeof("hoge")だと惜しいんだけど、 sizeof("hoge")==sizeof(char)*4 にならない?そしてcharが1バイトとは限らないから。。。 言い忘れたけど ・標準C++準拠 ・文字列はASCII文字しか入りません。 を想定しています。 ただしstrlenでもまあどうにかならないことはない。(配列を動的確保にすれば。)
>>88 $ cat -n foo.c
1
2 #include <stdio.h>
3
4 #define static_strlent(static_str, type) (sizeof(static_str)/sizeof(type) -1)
5 #define static_strlen(static_str) (static_strlent(static_str, char))
6 #define static_wcstrlen(static_str) (static_strlent(static_str, wchar_t))
7 #define static_mbstrlen(static_str) (static_strlent(static_str, char))
8
9 int main(void)
10 {
11 printf("char %d\n", static_strlen("sakuratan"));
12 printf("wchar %d\n", static_wcstrlen(L"さくらたん"));
13 printf("mb %d\n", static_mbstrlen("さくらたん"));
14
15 return 0;
16 }
$ ./foooo
char 9
wchar 5
mb 15
マルチバイトはもう知らん。
わざわざC++の規格読むの面倒だから後は適当に誰かやってくれるだろう。
90 :
88 :2009/06/18(木) 22:23:35
>>89 (sizeof(static_str)/sizeof(static_str) - 1)とすればchar/wchar_tの場合分けが不要になる。
(sizeof(static_str)/sizeof(static_str[0]) -1) ってことかな。 確かにそうだね。配列の要素数を得るマクロのちょっとした応用だった。
しかしそれは果たしてコンパイル時定数になれるのだろうか?
余裕でなれるんじゃないの?
ISO/IEC 14882:2003(E) 5.19 Constant expressions 1 ... An integral constant-expression can involve only literals (2.13), enumerators, const variables or static data members of integral or enumeration types initialized with constant expressions (8.5), non-type tem- plate parameters of integral or enumeration types, and sizeof expressions. Floating literals (2.13.3) can appear only if they are cast to integral or enumeration types. Only type conversions to integral or enumera- tion types can be used. ... (前後は省いた) 全く忙しいのにC++の規格を読むことになるとは、ちゃんと書いてあるね、sizeof expressionsって。 sizeof expressionsがわからない場合は、自分で規格書内を調べてね。
96 :
88 :2009/06/18(木) 23:14:43
いやはやすまない。 みんなマジでサンクス!
Win32(VC++2005) で作ってます。 思いつきでずぼらなクラスを書いてみました。 class CLocalTime { private: char buf[32]; SYSTEMTIME SysTime; public: CLocalTime() { } operator char *(); }; CLocalTime::operator char *() { GetLocalTime(&SysTime); sprintf_s(buf, 31, "%04d/%02d/%02d %02d:%02d:%02d", SysTime.wYear, SysTime.wMonth, SysTime.wDay, SysTime.wHour, SysTime.wMinute, SysTime.wSecond); buf[31] = '\0'; return buf; } これで、例えば printf なんかで使うときに、 printf("通過![%s]\n", (char *)CLocalTime()); ときちんとキャストすればちゃんと表示されるんですが、 printf("通過![%s]\n", CLocalTime()); だけで表示させるには、たぶん operator だと思うんですが、何を追加すればいいんでしょうか。 CAtlStringA なんかは後者できちんと表示されていてくやしいです。
98 :
デフォルトの名無しさん :2009/06/19(金) 17:16:20
Cに関する初歩的なポインタの質問です。 問. 1を入力すると「Jan」、2を入力すると「Feb」というように、その月の名前を返すプログラムを文字列の配列を利用して作れ 答. #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> char *mon(int n); ←←←←←←←←← int main() { int n; while (1) { printf("数値:__"); scanf("%d",&n); if(n == 0) break; printf("%s\n",mon(n-1)); } return 0; } char *mon(int n) ←←←←←←← { →→→→ char *month[] = {"Jan", ・・・略"}; return month[n]; } ここでポインタが出てくる理由がわかりません。 ここではmonthのアドレスをmonに集約させて表示させてるっていう認識でOKですか? また、配列を利用する以外に、もっと簡単に解答を返す方法ってあるんでしょうか?
>>98 あー。文字「列」について勉強しなおしましょう。
端的にいうと、C言語には文字「列」という型はないのです。
BASICでは文字列型というのがありました。A$とかB$とか。
でもC言語にはないんです。
ないから、文字列をやり取りするには非常に特殊な方法が必要なのです。
それがchar*なのです。
100 :
98 :2009/06/19(金) 17:26:20
>>99 素早いお返事ありがとうございます。
検索してみたところ、"プログラム中に「"ABC"」が出てくると、これ全体がアドレスの値になります" これがそもそも理解できてませんでした。
文字列について調べてきます。ありがとうございました。 100get
class A { protected: size_t global_a; } こんなかんじで protected な field を global 変数のように 扱いたいのです。いちど継承をしないと、その include 先の メソッドから操作するのは難しいでしょうか? > protected な field class DealWithA : public A { ... } class ConvertWithA : public A { ... } class TalkWithA : public A { ... }
あと class A << DealWithA << ActionDeal のように 二段階下の階層から、class A 大もとの 『protected な field』 に アクセスすることはできるでしょうか? どうぞ宜しくお願いします。
フィールドとかメソッドとか意味不明な単語がw ・・・メソッドはVCでは使うか。 「インクルード先のメソッド」の意味が不明ですが、 protectedメンバは派生クラスでないクラスからはprivateメンバとして扱われるので見えません。 派生クラスは基底クラスのメンバを継承するので (ただし、コンストラクタ、仮想でない代入演算子、仮想でないデストラクタを除く) 派生クラスの派生クラスでも奥底のクラスのメンバにアクセスできます。 多重継承の場合にいくつかの注意事項があるくらいでしょう。
>>104 当該サイトで紹介されている Exceptional C++ Style は
C++ の落とし穴を紹介する本の中でもことさらに難しいレベルで、
さすがはサッター先生と驚嘆すべき本です。
(同氏の著書 Exceptional C++ でメイヤーズすらもそう書いている)
初心者は読んでもちんぷんかんぷんでしょう。
言語仕様の微細に分け入れるので、むしろ混乱するだけかもしれません。
あと、当該サイト、コード間違ってます。
すぐにわかるレベルのtypoですが…。
106 :
デフォルトの名無しさん :2009/06/19(金) 23:56:27
質問させてもらいます。 error LNK2028: 未解決のトークン (0A00001D) "extern "C"〜 っていうエラーが出るんですが、問題の関数にはextern "C"がつけられてます。 この場合他にどういう原因が考えられるでしょうか?
>>106 関数の、宣言と定義の両方に extern "C" ついてる?
あとは普通のリンク間違いしか思いつかないな。
108 :
デフォルトの名無しさん :2009/06/20(土) 00:32:06
Visual Studio2008を使っているのですが、 sprintfを使うと 'sprintf' の宣言を確認してください。 というエラーが出て、 ネットで検索したところ、sprintf_sの書式に書き換えると良いと書いてあったので書き換えたところ warning C4024: 'sprintf_s' : の型が 2 の仮引数および実引数と異なります。 というエラーが。 どうしたらsprintfが使えるようになるんですか?
sprintf sprintf_s は書式が違う、パラメータをsprintf_sにあわせて増やす
>>108 多分書式間違えてる。すごい勢いで間違えている。ソースを全部貼れといいたいほどに間違っている。
ご存知のとおり、varargを利用するこの手の関数はいかなる文法上のミスも許されない。
111 :
デフォルトの名無しさん :2009/06/20(土) 00:37:33
>>109-110 すいません、きっと凄い勢いで間違えてます。
ただ本の通りにはしてるんです。できれば修正お願いします。
#include <stdio.h>
struct Data {
char name[32];
int age;
double bl;
double bw;
double bmi;
};
int struct_input(struct Data *);
int main()
{
struct Data Mydata;
char format[] = "%sさん(%d歳)のプロフィール\n"
"身長 = %5.1fcm, 体重 = %5.1fkg, BMI = %4.1f\n";
char buffer[256];
struct_input(&Mydata);
sprintf(buffer, format, Mydata.name, Mydata.age,
Mydata.bl, Mydata.bw, Mydata.bmi);
printf(buffer);
printf("%s", Mydata.name);
return 0;
}
続き int struct_input(struct Data *p); { printf("氏名__"); gets(p->name); printf("年齢___"); scanf("%d", &p->age); printf("身長(cm)___"); scanf("%lf", &p->bl); printf("体重(kg)___"); scanf("%lf", &p->bw); p->bmi = p->bw * 10000.0 / (p->bl * p->bl); return 0; } お願いします。。
sprintf(buffer, sizeof(buffer), format, Mydata.name, Mydata.age, Mydata.bl, Mydata.bw, Mydata.bmi);
114 :
デフォルトの名無しさん :2009/06/20(土) 00:39:43
>>107 回答ありがとうございます。
サンプルプログラムなので
そのへんはちゃんとなっているようです。
sprintf_s(buffer, sizeof(buffer), format, Mydata.name, Mydata.age, Mydata.bl, Mydata.bw, Mydata.bmi); _s忘れた
aprintf使っても警告になるだけでエラーにはならないと思うんだけど 設定によるのかしら?
>>108 #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
と書けば、sprintfがそのまま使える。
これはsprintfの呼出をできるかぎりsprintf_sに変換するようになる効果がある。
万能ではないが。
>>115-117 ありがとうございます。実行できるようになりました!
実行できなかったのはint struct_input(struct Data *p); セミコロンが原因でした。。
まだ、
'gets' の宣言を確認してください。
'scanf' の宣言を確認してください。 *3の合計4つの警告が残っているのですが、
警告は残ったままでもいいのでしょうか?
>>116 すいません警告でした。エラーは別の原因でした。。
>>118 エラーメッセージを略さないでちゃんと『全部』貼ってくれ。
_CRT_うんちゃらかんちゃらとか書いてあるだろ?
無視して問題ない。
>>119 すいません、今さらですが張らせて頂きます。
>c:\users\owner\documents\visual studio 2008\projects\struct03.c\struct03.c\struct03.c(34) : warning C4996: 'gets': This function or variable may be unsafe.
Consider using gets_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(279) : 'gets' の宣言を確認してください。
1>c:\users\owner\documents\visual studio 2008\projects\struct03.c\struct03.c\struct03.c(36) : warning C4996: 'scanf': This function or variable may be unsafe.
Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(306) : 'scanf' の宣言を確認してください。
1>c:\users\owner\documents\visual studio 2008\projects\struct03.c\struct03.c\struct03.c(38) : warning C4996: 'scanf': This function or variable may be unsafe.
Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(306) : 'scanf' の宣言を確認してください。
1>c:\users\owner\documents\visual studio 2008\projects\struct03.c\struct03.c\struct03.c(40) : warning C4996: 'scanf': This function or variable may be unsafe.
Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(306) : 'scanf' の宣言を確認してください。
CRTうんちゃら書いてました。
問題無いんですね、ありがとうございました!
gets この関数(もしくは変数)は安全でない可能性があります gets_s を使うことで安全になります。 こまけえことはいいんだうるせえだまれ、と思うなら _CRT_SECURE_NO_WARNINGS を使ってください。 と、書いてます。
あ、それと、gets関数というやつは「常に悪」である関数だよ。
123 :
デフォルトの名無しさん :2009/06/21(日) 07:33:13
質問です。 m個のデータの中からn個のデータを無作為に抽出したい場合、どうすればいいですか?
乱数を用いて、m個のデータテーブルからn個のデータを取り出す。 一度取り出されたとこは、なしフラグを立てて再度読まないようにする。 無い所が引かれたら再度乱数を取る。n個そろうまで繰り返す。
>124 まあ、楽だよな
126 :
123 :2009/06/21(日) 09:04:45
どうもです。
data a[m], b[n]; //input(a); for(i = 0; i < n; ++i) { swap<data>(a[i], a[rand()%(m - i) + i]); b[i] = a[i]; }
128 :
デフォルトの名無しさん :2009/06/21(日) 11:38:51
質問です。 VC++2008にて #pragma once class test { private: static int a; //テスト変数 public: test(void); ~test(void); static void tekitou(int b){ //テスト関数 a = b;//☆☆ } }; このクラスを別のファイルから test::tekitou(5);//☆☆ みたいな感じで呼ぶと main.obj : error LNK2001: 外部シンボル ""private: static int test::a" (?a@test@@0HA)" は未解決です。 C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\Project1\Game\Debug\Game.exe : fatal error LNK1120: 外部参照 1 が未解決です。 というエラーがリンク時にでるのですが、原因は何でしょうか? //☆☆と入れたどちらかの行を削除するとリンクも通ります。ヘッダファイル等はきちんと渡しているはずなのですが…
int test::a; をソースに書くとよい
ありがとうございます。通りました。 クラス読み込んだ際に、aも認識してくれてるはずと思い込んでいたのですが、してなかったんですね…
まず「宣言」と「定義」の違いを学ぶんじゃ おまえのソースには宣言しかなかったのじゃ
132 :
デフォルトの名無しさん :2009/06/21(日) 16:10:01
すみません。 Cを現在習得中なんですが、自作サンプルにて困ったことがあります。 構造体に電話番号と氏名のデータを入れているんですが、それをファイルに記憶しています。 で、好きな番号の後に新規データを入れれるようにしたんですが(fseek関数を使って)、 好きな番号のデータを削除することができません。ファイル処理はランダムアクセスで データを消去することはできないんでしょうか?
Cの扱うファイルは、バイト列。 ランダムアクセスしても、中を抜くことはできない。
134 :
デフォルトの名無しさん :2009/06/21(日) 16:16:33
>>133 どうもありがとうございます。できないんですか(´・ω・`)
ここまで来たんで、意地でもやりたいんですが、制御文字の
BSとか使ってもできないですかね・・もしできるなら、自分で工夫します。
135 :
デフォルトの名無しさん :2009/06/21(日) 16:19:40
136 :
134 :2009/06/21(日) 16:26:03
>>135 ありがとうございます。ぜひ、それを使い作ってみようと思います。教えてくださり、ありがとうございました。
できると聞いて、とてもうれしい・・
memmoveを使うというのは、いったんメモリに読み込んで、ずらして書き直すってことだよ。
138 :
134 :2009/06/21(日) 16:40:27
それでもいいお。
139 :
デフォルトの名無しさん :2009/06/21(日) 17:25:21
C++ の動作の質問です。以下のようなクラスがあったとして、ifブロックのスコープ内で文字配列のポインタをセットした時、 スコープを外れてもそれは有効な内容として保持されてるんでしょうか。 Class ClsA { private: char* p; public: void setStr(char* pt) { p = pt; } }; int main() { ClsA ca; if(TRUE) { ca.setStr("ABC"); } // この時点でインスタンス内の"ABC"は保持されているのか } もし、ブロックのスコープから外れても、インスタンス ca が保持するポインタの指す先は消えないとしたら、 この文字配列は delete しなければなりませんか?
140 :
デフォルトの名無しさん :2009/06/21(日) 17:27:34
スコープを外れていないので、保持されている。
定数文字列”ABC”がプログラムが終了するまで存在する
>>139 保持されているが、deleteすべきものがない
>>140-141 ありがとうございます。つまりこれは、
グローバルスコープにある char型配列(自動変数)と同じ、って考えていいんでしょうか
変数ではなく定数
145 :
デフォルトの名無しさん :2009/06/21(日) 17:34:18
グローバルなのに自動変数とはこれいかに? 自動変数の自動とは、レジスタやスタックで確保されているということじゃないのか?
ごめんなさい。自動変数じゃなくて定数。 ちなみに、何を不安に思っているかと言うと、 { char a[3]; a[0] = 'A'; a[1] = 'B'; a[2] = 'C'; ca.setStr(a); } // スコープを外れた時、ca の中のポインタは有効な物として使えるか のようにした時と、動作的にどう違うのかがわからないのです。ちなみにこの例だときっとアウト。 しかし定数ならOKって、どうして?
それが、自動変数と定数の仕様だから
素直にstringあたり適当につかっちゃいなYO
149 :
デフォルトの名無しさん :2009/06/21(日) 17:52:37
>>147 >>146 のソースでも、大本の文字は定数として書かれていて、char型配列はそのメモリ領域のアドレスを指している
そのアドレス値をコピーしたポインタを使っているって事は
→ 定数領域を指すポインタになっているので、プログラムが終了するまで保持される。
スコープを外れた時、char配列 a そのものは自動変数なのでスタックから削除されるが、
定数領域そのものはプログラム終了まで解放されない
→ その解放されない領域をポインタは指しているから、結果的に有効である
って解釈でいいんでしょうか
あ、ちょっとまて、配列は自動変でそのポインタは壊れる
壊れるっていう表現は正しくないな、そのポインターの先は保障されない。 が正しいか
>>151 壊れるんですか・・・ もし壊れるとするとますます
ca.setStr("ABC"); と、
char* a = "ABC";
ca.setStr(a); の、
違いがわからなくなってくる・・・ 一旦スコープ上に自動変数の形で置いたらアウト、って事なんでしょうか
直で"ABC"を渡した時は、その受け手はメソッド内の変数だから、って言う
定数は壊れない、 定数を参照する自動変数はスコープを外れたら保障されない。 定数の値を入れた自動変数はスコープを外れたら保障されない。 簡単だって、自動変数はスコープを外れたら保障されない。 だけ
>>154 そうすると、
ca.setStr("ABC");
と、置いた時、動作の順は 「定数 → 引数 → メンバの変数」 って移り変わりますが、
それでも大丈夫なんでしょうか。 あるいは
class ClsA {
public: char* p;
};
ClsA ca;
ca.p = "ABC"; //これなら確実
みたいにした方がいいんでしょうか。何度もすみません
上は、定数のアドレスデータが渡されているだけなので、自動変数を 中継に使っただけだから問題ない。 もちろん下は、定数のアドレスを入れているから問題ない。 この場合はどちらも問題ない。 上の自動変数は単なる中継、中継後壊れても問題は無い。
この場合の中継する自動変数は 引数のことな。間違えないように
あああそうか! 上の例の中継(引数)は自動変数でもあるけど、
自分が消える前にアドレスをメンバにコピー(アドレスの値渡し)して死ぬから、それはそれで問題ないって事ですか
あれ?でもそうすると
>>153 の下の例(char* に一旦アドレスを取り、そのアドレス値をメソッド引数に値渡しする)も、
同じ状態になる気がするんですが、あっちも大丈夫って事でしょうか
定数文字列の先頭アドレスが入るだけだよ
char a[3]; a[0] = 'A'; a[1] = 'B'; a[2] = 'C'; と char* a = "ABC"; は違うよ
なんかわかってきました。 1) char a[3]; a[0] = 'A'; a[1] = 'B'; a[2] = 'C'; // スコープ外れたらポインタの先は保証されない ca.setStr(a); 2) char* a = "ABC"; // インスタンス消えるまでポインタは有効 ca.setStr(a); 3) ca.setStr("ABC"); // 2と同じ この中で 1だけがアウトな理由は、1だけは直で定数のアドレスを指していないから。って事ですね! なんか納得できました。 スレ汚し失礼しました。 ありがとうございました。
>1だけは直で定数のアドレスを指していないから そ、これが大正解
ちなみに自分の理解のまとめ:
>>163 の2と3のケースは、即値の書かれたメモリ上のある1点を直接指していて、その領域(この場合は定数の)はプログラム終了まで解放されない。
1のケースは、「定数1文字の書かれた領域を示すアドレスの、そのアドレステーブルの先頭の、」 アドレスをポインタにコピーしているので、
配列(自動変数)に寿命が来たとき、コピーされたポインタの指す先は保証されなくなる。
似たような事で悩んでいる人がいるとあれなので、メモしておきます。 ありがとうございました。
なんか1のケースの解釈がへんじゃね? 定数1文字の書かれた領域を示すアドレスなんてものは使ってないよ。
>>166 char a[3];
a[0] = 'A';
この時、a[0] って言う変数は、定数領域にある 'A' を指していて、
a は自動変数領域にある、a[0]〜a[2] のアドレステーブルを指している。これは、
Foo f[3]; であっても同じで、配列名 f は、アドレステーブルを示す物(値はそのアドレステーブルの先頭アドレス)
って、解釈じゃ間違いでしょうか。 なんか長引いて申し訳ないです
168 :
123 :2009/06/21(日) 19:01:25
>この時、a[0] って言う変数は、定数領域にある 'A' を指していて、 指してない
文字を画面の真ん中あたりに表示させたいのですが、 座標を指定する方法がわかりません。 どうすればいいのですか?
>>169 こういうイメージを持っていました。
メモリマップイメージのモデル:
自動変数領域 ※スコープの終了と共に解放される
+0 +1 +2 +3 +4 +5 +6 +7
8000 10 80 11 80 12 80 00 80 a[0] a[1] a[2] a
8008 00 00 00 00 00 00 00 00
定数領域 ※プログラムの終了と共に解放される
8010 41 42 43 00 00 00 00 00 ABC
8018 00 00 00 00 00 00 00 00
1は単に値のコピーだね。だからcharが破壊されると値も破壊される。
ああ・・・ int i = 10; と同じような値のこぴー・・・ なんか深く考えすぎたかもしれない
ためせボケ うぜぇんだよ
で、試すとどんな状況でもたいがいちゃんと表示されちゃうんだよな。 メモリの中身がゴミになったかどうかは単純な実験では確認できない。 C言語知らない人間にはこのことが理解できない
アドレス理解してるじゃねぇか なんでメモリがわかんねーんだよ 新手の嫌がらせか
178 :
172 :2009/06/21(日) 23:04:01
>>176 それ!表示されちゃうんです。 使う分にはそれでいいんだけど、動作を知りたい。
で、知らずに少しづつリークしてくような作りを書きたくなかった。 だから知りたかった。
>>177 嫌がらせじゃないです。 じゃあ
>>172 のイメージで合ってるんですか?
あのメモリマップは、あくまで自分の想像です。 動きを観察したらああなのかなぁって思った。
元々、Z80A でずっとアセンブラを書いてた事があるので、自分ならああいうイメージにするって思った。
でも、
>>169 さんに 「指していない」 と指摘を受けたので、そのイメージじゃないのかなって確認の為に書きました。
>>172 のモデルでは、変数はアドレスを指しています。 もし違うとしたら、 8000H から 41 00 42 00 ・・・ って収まる事になる。
でも結局、即値が入ってるにしても何にしても、実際には自動変数領域にサイズ情報くらいは格納してると思うので、
不定バイト長であっても処理系がうまいことしてくれるのかなと考える事にしました。 長々とすみません。
やはりアセンブラからCへの昇格だったか int a = 10; int *p = NULL; p = &a; printf( "%d\n", *p ); これを理解しろ クラスやらポインタが指してるとかはそれ以後の問題だ
180 :
デフォルトの名無しさん :2009/06/21(日) 23:14:39
ほとんど読んでないけどデバッガ使えばいいんじゃないの
不定バイト長でよろしくやってくれると思ってるのか? printf( "int:%d\n", sizeof(int) ); printf( "double:%d\n", sizeof(double) ); printf( "char:%d\n", sizeof(char) ); printf( "char[4]:%d\n", sizeof(char[4]) ); で、自分の環境を調べろ 処理系がうまいことやるわけない
>>178 'A'と単純に書いたとき、それは'A'の文字コードとして扱われる。
それを配列の要素に代入したとき、配列のメモリ領域にその数値が格納される。
"A"と書いたとき、Aと\0が静的な(場合によってはReadOnlyな)連続領域に配置され、
その先頭アドレスを表す。
>>179 その内容だと、多分
>>172 のモデルになると思います。
変数領域のアドレスの即値を、ディープコピーでポインタ変数の値としてコピーしている
>>182 ああああああ ありがとうございました!
それが聞きたかった。 定数 'A' と 定数 "A" の、明確な違い。 すっきりしました、ありがとう!
>>184 よかったw
たぶんあなたはポインタで詰まることはなさそうなので、今後は楽かもw
char buf[256]; string st; st = buf; のようにしたいのですが当然コンパイルエラーです どうやってstring型にchar配列を代入できるのでしょうか?
st = (string)buf;
189 :
186 :2009/06/22(月) 07:33:36
えええ!? 187がコンパイルできるなら186も問題ないはずなんだけど。
これ以上は通報するぞ?
192 :
デフォルトの名無しさん :2009/06/22(月) 08:34:34
それまじでいったん
st = (string)buf; //
>>186 の期待とは違う動作
と
st = buf; // 問題ない動作
俳味がぜんぜん違います。
コンパイルエラーは、#include が正しくない
char buf[256]; string st(buf); これがベスト
だから st = buf; はコンパイルエラー出ずに通るっしょ? コンパイルエラーが出るとか嘘を書くなっつーの
質問者逃亡
197 :
デフォルトの名無しさん :2009/06/22(月) 11:13:19
assert()に失敗した時に値を表示するようにできないでしょうか? 例えば assert (x >= 0 && x < WIDTH); の行でアサートで落ちたときにxの値を表示してほしいのです。
授業で提示されたサンプルでは、 srand(time(NULL)); secret_number=rand() % 9 + 1; で1〜9の乱数を生成しているのですが、このようなやり方で命令を使わずに 4桁の乱数(1000〜9999)を生成するにはどうすればいいのでしょうか?
rand() % 9000 + 1000
200 :
デフォルトの名無しさん :2009/06/22(月) 11:23:29
#ifdef NDEBUG #define assert_or_show(a,b) ((void)0) #else #define assert_or_show(a,b) ((a) ? (void)0 : \ wsprintf(g_sz, "file %s, line %d: (%s), %d", __FILE__, __LINE__, #a, b), \ MessageBox(NULL, g_sz, NULL, 0)) #endif char g_sz[1024]; assert_or_show(x >= 0 && x < WIDTH, x)
201 :
デフォルトの名無しさん :2009/06/22(月) 11:24:15
>>199 それだと、 1000~6766の出現確率が6767~9999の出現確率の1.33倍になるぞ。
(RAND_MAXが32767の場合)
203 :
197 :2009/06/22(月) 11:33:17
>>200 完璧です。欲しかったのはそういうASSERTです。
恐れ入りました。
これからもっともっと精進します。
204 :
デフォルトの名無しさん :2009/06/22(月) 11:35:52
srand(time(NULL)); secret_number = (int)((rand()/((double)RAND_MAX+1.0f))*(10000-1000))+1000;
>>199 >>204 上ので出来るみたいですね。数学に疎いものでよくわかりませんが・・・
命令というより関数?ですか。どうもありがとうございました
BCCでDirectX9は使えるの? ライブラリは7までしかないって聞いたけど
208 :
デフォルトの名無しさん :2009/06/22(月) 12:39:41
>>206 ありがとうございます。無事修正して提出できました。
enum ID { ID_ABC, ID_DEF, ID_GHI, ... }; struct IDITEM { enum ID id; const char *name; }; という定義があったとして、 struct IDITEM table[] = { {ID_ABC, "ID_ABC"}, {ID_DEF, "ID_DEF"}, {ID_GHI, "ID_GHI"}, ... }; という宣言を簡単にマクロでつくれないでしょうか。 イメージとしては #define DECL(id) {id, "id"} struct IDITEM table[] = { DECL(ID_ABC), DECL(ID_DEF), DECL(ID_GHI), ... }; みたいな。でも id を " で囲む方法がわかりません。"##id##" じゃないし... どうすればいいでしょう?
#define DECL(id) {id, #id} の、どこがダメなんですか?
クラス定義の中でusingを使いたいんですが、どうやれば使えるようになるんでしょうか? とりあえず試したのはしたの2パターンですがだめでした class Class { using std::string; // 失敗! std::string str; //<- string だけにしたい }; namespace name { using std::string; class Class { string str; }; } // name内のほかの場所でもusingが有効になってしまう。失敗!
>>215 不可能。
擬似的に実現したいなら
class Class {
typedef std::string string; // 成功
string str; //<- string だけ
};
これで満足?
満足です。ありがとうございました メンバの引数に長い名前空間が沢山出てきたときのタイプ量を減らしたかっただけなのです
仮想関数にテンプレートを適用したいのですが、どうやれば使えるようになるんでしょうか? template<typename T,unsigned U>struct A{virtual int operator()(T&)const{return U;} template<typename T>struct BASE: A<T,0>,A<T,1>A<T,2>{} template<typename T>struct B:BASE<T>{template<unsigned U>int A<T,U>::operator()(T&);} としてもだめでした。
>216 そのtypedefは面白いな
バネとダンパーにぶら下がった重りの変位を求めるプログラムなのですが #include<stdio.h> #include <math.h> void euler(double *,double *,double *,double *); double acceleration(double,double,double); main(){ double x,v,t,dt,tt; dt=0.1; x=0.05; v=0.0; t=0.0; tt=300.0;//出力を開始する時刻 while(t<tt+10.1){ if(t>=tt){ printf("%lf\t%lf\n",t,x); } euler(&x,&v,&t,&dt); t+=dt; } return(0); }
221 :
220 :2009/06/23(火) 01:53:14
/*Function euler()*/ void euler(double *x,double *v,double *dt,double *t){ *x+=*v**dt; *v+=acceleration(*x,*v,*t)**dt; } /*Function acceleration()*/ double acceleration(double X,double V,double T){ double a; a=-(0.5*V)-X+sin(2.0*T); return(a); } 出力結果に1.#QNANOという数字が出てきてしまうのですが、これはなぜですか?
> *x+=*v**dt; キモっ >*v+=acceleration(*x,*v,*t)**dt; キモっ キモっ
>>220 オーバフローだね> 1.#QNANO
ためしにtt=300.0じゃなくてtt=60.0ぐらいから表示してみると、
65秒あたりからX座標がめちゃくちゃ発散しちゃってますぜ
tとdtはポインタで渡す必要ないじゃん
別にアドレス渡しでもいいじゃん
int StrToIntDef(const char *s, int def) { char *err; int val = strtol(s, &err, 0); return (ア); } のとき、(ア)の部分は 1: err ? def : val 2: *err ? def : val 3: (err && *err) ? def : val どれがいいの?
>>227 2じゃね。errにNULLが返ることはない
この仕様だと strtol("", &err, 0) とした場合に err[0] = '\0' になるんだよな.......
名前空間を消すためのtypedefに、templateのtypedefを使いたいんだけど こんなごまかし方以外になんかないかな? template <typename type> class smart_ptr { public: typedef std::tr1::shared_ptr<type> shared; typedef std::tr1::weak_ptr<type> weak; }; class CHoge { public: ...; private: smart_ptr<int>::shared p; };
thxです しかし、求めてるものとはちょっと違いました なんで名前空間を隠蔽したいかというと 今vc++で使ってるstd::tr1::が将来std::になるらしい(?)ということを聞いたので 今後std::tr1をできるだけ手間無くstdに変えられるように書きたいなと思ったからです namespace std = std::tr1みたいなことができれば、1行消すだけでstd::tr1→stdになって楽なんですけどできませんでした マクロしかないんでしょうかねぇ
namespace std { using namespace std::tr1; }
>>232 書いた直後にためしたので解決?できた。できてんのかな?
namespace std {
using namespace std::tr1;
}
std::shared_ptr<hoge> hoge;
>>233 書き込む前にレス気がつきませんでしたがthx
236 :
231 :2009/06/23(火) 23:05:47
>>232 具体的にそう言ってくれないとさぁ・・・。
エスパーじゃな…(ry
std::tr1::はそのままの方がいいと思うのだが。
むりにstd::名前空間に引っ張ってこない方が。
だって将来std::になるだろうという予定なだけだし、
どうしても直したかったらgrepで適当に置換すればいいだけじゃないか。
237 :
231 :2009/06/23(火) 23:07:30
>>236 ×どうしても直したかったら
○実際にstd名前空間に入れもらえて、
○さらにC++0xが一般的にサポートされるようになった時
○一斉に直したかったら
の意味ね。
grep使ったこと無いです>< こんど使ってみます
>>238 ああ、知らないなら俺のレスを
単に「検索して置換」って読み替えてくれてもいいよ。
gotoなんか一生使うな。って、スレ違ってないか?
grepがgotoにみえるほどつかれていたんだろうよ
243 :
241 :2009/06/24(水) 14:19:59
理解。
virtualついてないメンバ関数はなるべくオーバーライドしないほうがいい、でおk?
ポリモルフィズムと名前の隠蔽がどういうものか理解していれば 別に非仮想関数をばんばんオーバーライドしてもいいぞ。 でもしないほうがいいのは確かだね。 厄介ごとにわざわざ首を突っ込む必要はないから。
>>244 とりあえずEffective C++を読むといいよ。
道しるべになってくれる。
Effective C++はまさに今読んでます 隠蔽の仕組みも大体わかってるつもりなんですが ベースのポインタから呼んだときとサブの変数から呼んだときで 呼ばれる関数が違うのがじゃっかん気持悪くて・・・ 後のメンテナンスがめんどくさそうな気がするからオーバーライドしないほうがいいのかなー、と
>>247 >>247 > ベースのポインタから呼んだときとサブの変数から呼んだときで
> 呼ばれる関数が違うのがじゃっかん気持悪くて・・・
若干どころじゃない!
そういうのは代表的なクソ設計の一つ。
君の感覚が正しい。
すなわち
基底クラスのポインタに、派生クラスの変数のアドレスや
基底クラスの変数のアドレスを入れて同じインターフェースで操作する
というのを
ポリモーフィズムpolymorphism的な使い方
という。
例:
BaseWindowClass{virtual void visualize(){}};
Derived_1_WC : BaseWindowClass{void visualize(){}};
Derived_2_WC : BaseWindowClass{void visualize(){}};
にて
BaseWindowClass * p = new BaseWindowClass();
BaseWindowClass * q = new Derived_1_WC();
BaseWindowClass * r = new Derived_2_WC();
のような状況の時、
Func(const BaseWindowClass * arg){arg->visualize()}
にp,q,rを全部区別無く渡せる。
そしてポリモーフィズム的な使い方をされることが前提の場合、
そのメンバ関数はvirtualにすべき。
逆にポリモーフィズム的な使い方をされないなら
virtualでないメンバ関数をオーバーライドすることもありえるだろう。
249 :
248 :2009/06/24(水) 16:23:54
逆に 他人の作った基底クラスが ポリモーフィズム的な使い方をするハズのクラスなのに virtual宣言されていないメンバ関数がある場合、 「そのメンバ関数はオーバーライドしないでくれ」 という基底クラス設計者のメッセージと受け取るべき。
インターフェースの継承では仮想以外いじらない ベースの一部の機能が欲しいだけのときとかは臨機応変に可 ということですね。参考になりました。thxです
基底クラスの一部分しか機能を使わないなら継承しちゃダメよ。 継承は「is a」の関係でないといけない。 まぁ、そんなことは気にせず、例えばvectorとかstringとかを継承して おもしろいことにしちゃうのもおもしろいけどね(初心者のうちは…)。
インターフェースの継承では仮想以外いじらない その他の場合はいじらないでいいならいじらないが臨機応変に可 こ、これでおk・・・かな
253 :
248 :2009/06/24(水) 17:18:36
俺は
>>251 とは別人だが。
>>252 > インターフェースの継承では仮想以外いじらない
『Effective C++』用語でいうところのインターフェースの継承とは
純粋仮想関数のオーバーライドのことだったと記憶している。
polymorphicな使い方をされる想定の基底クラスについて
純粋仮想関数(定義無し)=>インターフェースのみの継承。実装は各自で0から作れ。
純粋仮想関数(定義あり)=>インターフェースの継承。実装は各自で作れ、ただし基本コードは提供してあげるよ。
仮想関数=>インターフェースの継承。ただしデフォルトの実装も提供するので必ずしも各自で作る必要はない。
非仮想関数=>インターフェースと実装の継承。オーバーライドするなってことだ。
ここまでは分かってますかい?
なお、
polymorphicな使い方をされない想定の基底クラスのメンバは
デストラクタ含め全て非仮想関数になっている。STLなど。
逆に言えば
仮想関数を持つクラスはpolymorphicな使い方をされることを想定
しているわけであり、デストラクタも仮想になっている。
以上、全てpublic継承の話ね。
仮想化の種類と特徴はわかってます public継承でベースにvirtualがひとつでもあるなら それはポリモーフィックな使い方をすることが前提→virtual以外はオーバーライドしない ほかの場合は適宜、ということでしょうか?若干混乱してきた もうちょっとEC++読み進めたほうがよさそうですね
>>254 > public継承でベースにvirtualがひとつでもあるなら
> それはポリモーフィックな使い方をすることが前提→virtual以外はオーバーライドしない
> ほかの場合は適宜、ということでしょうか?
あってるよ。
まあ、それだけ理解出来ていればすぐ慣れるさ。
がんがれ
>>254 意味は理解できてても、どういった場合に使うのが妥当かが理解できてい
ないと思われ。単に経験だな
深さ優先探索とスタックの関係 幅優先探索とキューの関係がまったく分かりません。 用は何がしたいんですか? 教科書の説明だとそれぞれのノードに 番号つけるだけみたいな説明なんですけど 番号つけるのとスタック、キューがどうリンクしているのかまったく分かりません。 それと教科書に ”グラフの点は、深さ優先探索ではスタックで管理され 幅優先順ではキューで管理される” とありますが、結局は番号とその番号に収納されてるデータを 配列で対応させるのが目的なんでしょうか? よろしくお願いします。
探索がしたい エスパーすると CPU時間が異なる
エスパーすると >配列で対応させるのが目的なんでしょうか? 違う
マジなエスパー要請キタ!
>>258 データが同じなら、CPU時間にそれほど違いは無いかな
まあキューの方が遅そうだが。
エスパーに対してエスパーしてみた。メタエスパー?
構造体に関連してtypedefを勉強していて分からない箇所がありました。 --------------------------- typedef struct _tagData { int age; double bl; double bw; } MYDATA, LPMYDATA; とすると、_tagData型の構造体変数を宣言するとき MYDATA mydata; と書くことができます。 また、この構造体へのポインタを宣言するときも LPMYDATA lpmydata; と書くことができます --------------------------- 変数を宣言するまでは理解できるんですが、 MYDATA mydataと書くことができるってくだりが分からないんです。 そもそも意味が・・。 分かりやすく解説していただけませんか?
>>262 typedefしておくと、その型を使うときstructキーワードがいらないってこと
-----------------
struct _a {int foo; double bar;}; /*「struct _a」型を普通に定義 */
int main()
{
struct _a mydata; /* 使うときにもstructキーワードが必要 */
}
-----------------
struct _a {int foo; double bar;}; /* 上と同じ「struct _a」型を… */
typedef struct _a A; /* このようにtypedefすると */
int main()
{
A mydata; /* structキーワード不要、型名Aだけでよい *//
}
図解
typedef ○○○ 定義名
※○○○は改行して記述してもよい。定義名はカンマ区切りで複数書いてもよい
↓
typedef ○○○
○○
○○
○ 定義名
※○の所に、struct の宣言を埋め込んでみよう。 何故そうしたいのか、は
>>263 参照
>>263-264 なるほど、ありがとうございます。
構造体で使う場合としては単にstructなどを省略するための関数と捉えていいんですよね?
大規模なプログラムを書くときにはこれが活きてくるのでしょうか?
本に書いてあるレベルではメリットがあまり感じられないので。。
>265 そんな感じ。 もし仮に、その構造体をtypedef無しで5個とか10個とか使うことになった……と想像してみればいいと思うよ。 たぶんイヤな気持ちになれるから(笑) 他にも、1つのプログラムを複数の人で分けて書いている時や、 既存のライブラリ&フレームワークを使って開発するっていう時にも役に立つ。 単なるデータの受け渡しに使うだけなど、その構造体の中身を直接弄らない限り、 MYDATAの中が具体的にどうなってるか知る必要が無くなる。 つまり、使うだけならintとかdoubleとかと同列に並べることが出来るってわけだ。 もし今後、Cでファイル処理をやる機会があったら、よく見てみるといいよ。 「FILE」って名前の型が出てくるはずだから。 僕らはFILEの構造がどうなってるか知らなくてもいいし、そもそも構造体とは限らないかもしれない。 それと、蛇足かもしれないけど、最後に1つだけ。 typedefは「関数」ではないからね。 凄く細かいところかもしれないけど、もし勘違いしたままだと大変だから。
>>266 ほんと助かりました、ありがとうございます。
今の自分にはあまり必要がないですが将来的に必要になるものですね。
FILEはもうすぐファイル入出力の項に入るのでそのとき見てみます。
関数じゃなくてデータ型でしたね、いまいち関数との違いも分かってないような
レベルでした。。ありがとうございました!
>>266 > 凄く細かいところかもしれないけど、もし勘違いしたままだと大変だから。
お前やさしいやつだな。
俺だったらもっと厳しく言うと思う。
>>267 >関数じゃなくてデータ型でしたね、
>いまいち関数との違いも分かってないような
>レベルでした。。
typedef自身は関数でもなければデータ型でもありません。
typedefはキーワードです。(宣言指定子)
どういたしまして。
>>255 そうか?
常にvirtual以外はオーバーライド禁止だと思うけど
宣言指定子って型指定子も含むんだけど
データ型がキーワードじゃないとも読める
274 :
デフォルトの名無しさん :2009/06/25(木) 13:46:22
スレ違いかとも思うのですが、他に質問できる場所を見つけられなかったので、書かせていただきます。 vc2003にてメールの送信を行おうとしています。 メール送信の最初のheloの送信時について質問なのですが、 sendを行う中身を @"HELO name\r\n" A"HELO name \r\n" (Aは\r\nの前にブランク有り) とすると、Aでは [501 5.0.0 Invalid domain name]を返却されることがあります。 Aでもheloが通るマシンは合ったのですが、 SMTPサーバによっては、"name "を名称と取ってエラーを返却するということなのでしょうか? Aではエラーが発生しましたので、@の形に修正するのですが、 @では私が接していないサーバでもエラーなく動かせるのでしょうか? このような細かい部分を載せてあるHPが見つけられなかったため質問させていただきました。 他にもメール送信時の決まりごとの参考となるようなHPを教えていただけると助かります。
275 :
デフォルトの名無しさん :2009/06/25(木) 13:56:43
>275 知ってるか? そのURLは、大学内からじゃないとアクセスできないんだぜ? つーかその、なんだ。俺の母校じゃねーか(笑)
>>274 >他に質問できる場所を見つけられなかったので
なんだろう…ネットワーク?ちょと違うか。
>SMTPサーバによっては、"name "を名称と取ってエラーを返却するということなのでしょうか?
RFC では、<CRLF> の前の空白を許容せよと書いてある。が、
許容しないサーバがあるというなら、あるんだろう。
>@では私が接していないサーバでもエラーなく動かせるのでしょうか?
互換性の為にHELOは通せ、と書いてあるし、そこは多分大丈夫かと。
>他にもメール送信時の決まりごとの参考となるようなHPを教えていただけると助かります。
↓こことか。
ttp://www.puni.net/~mimori/smtp/
278 :
デフォルトの名無しさん :2009/06/25(木) 16:48:17
>>276 やっぱみれないか(;Ц;)
母校なら・・・なお、頼む!
>278 だから外部からの接続じゃ見れねーから、どうしようも無いんだってば。 あと、人に質問するときは、質問の仕方と態度を覚えような?
ロダに転載しろよ 著作権とか言われたら責任取れないけど
確かライツアウトって、どのボタンを押すかという組み合わせの問題なんだよな。 押す順番は関係ないし、2回以上同じ場所を押す必要はない(それは押さないのと同じ)、っていう。 >280 問題を読んだところで「for文で1個ずつチェックしろ」の一言で終わりそうだけどな。 もう何年も昔だけど、Cの基礎しかやらないような講義内容だったし。 問題作成のところは、何もライトが点いていない状態から ランダム(または任意)の箇所のボタンを押した状態にする……くらいかね?
283 :
255 :2009/06/25(木) 20:28:45
>>270 それは安全だが「常に」ではないと思う。
例えば非仮想デストラクタを持つ基底クラスでオーバーライドなんて
よく・・・はないけど、たまにはあり得てもおかしくない。
さらにいえばshared_ptrで子クラスのインスタンスのアドレスを親クラスの
スマートポインタにいれてもおkなんだから。
どうして「常に」ではないのか、理由もEffective C++に書いてあるね。 Effective C++は本当に偉大な本だ。
private継承の時とか?
public継承で非仮想関数をオーバーライドするのがベターって状況、具体的にどんなのがあるの?
俺は後半の手口のメリットも知りたい
例えば、vtblがそのクラスを他の言語に渡す邪魔になるとき。 メモリコスト、演算コスト、他のコードとの互換性などの理由で どうしても汚い実装が必要になる現実があり その現実に対処するために「プログラマはすべてを知っている」という原則に立っているのは C++がCから受け継いだ実用性のひとつ、というのがメイヤーズの回答の要約かな。
ふむ。
>>283 はその「泥臭いこと」を指して「常に」ではないといったのかな。
290 :
283 :2009/06/25(木) 22:20:31
>>288 さんありがとう。
>>287 > 後半の手口のメリット
俺も知りたいわ。
「非仮想デストラクタを持つ基底クラスを継承した派生クラスの
インスタンスをnewで生成してRAIIにもとづきshared_ptrに渡す」
こんな状況が起こるのはレアケースな気もするが、
知識として知っていればこんな時にも大丈夫
ってなだけかね。
>>290 基底クラスのデストラクタを仮想に変更できない、のっぴきならない事情における最終手段の話だよね?
>>291 他人が書いたクラスとかね。
STLではあまりやりたくないけどそういう最終手段もありってことだろうと思う。
pimplで役立ちそうだ。
他人が書いたクラス程度の話なら仮想デストラクタに変更すればいいのに
RAIIにもとづきとかなんかおかしい。おかしいよな?
多態性を利用したコードでメモリリークが発生するのを避けたいかつ、 RAIIな動作にしたい場合にしぶしぶそうするってことだよね? なんかRAIIが絶対であるかのように読めたから。誤解ならごめんね。
297 :
295 :2009/06/25(木) 23:18:57
>>296 基底クラスbaseが仮想でないデストラクタをもつ場合、
その派生クラスderivedをnewしてbase* pに渡して
delete pするとメモリーリークどころか未定義動作になるはずだが。
要は
polymorphismを利用したコードに使われることを想定されていないクラス
を基底クラスにしてpolymorphicに使いたい以下略
ん? 基底クラスが非仮想デストラクタで、 基底クラス *p = new 派生クラス delete p 派生クラスのデストラクタが呼ばれないだけだと思ってた。 未定義なんだったらますますだめじゃね?
299 :
297 :2009/06/25(木) 23:32:25
>>298 >派生クラスのデストラクタが呼ばれないだけだと思ってた。
いや、厳密には未定義なんだわ。
5.3.5
if the static type of the operand is different from its dynamic type,
the static type shall be a base class of the operand’s dynamic type
and the static type shall have a virtual destructor
or the behavior is undefined.
これを俺なりに訳すと
もしオペランド(演算対象)の静的な型と動的な型が異なる場合、
静的な型は「オペランドの動的な型の基底クラス」になる。
そしてその静的な型は仮想デストラクタを持つべきであり、
さもなければ挙動は未定義である。
ところが
boost::shared_ptr<基底クラス> sh_p(new 派生クラス());
これだとsh_pが破棄される時に自動的にdeleteされるわけだが
基底クラスが非仮想デストラクタでも未定義にならないというすげー代物。
300 :
299 :2009/06/25(木) 23:34:08
そろそろ寝ないと次の日がやばいから寝るわ。 明日早いんで。 おやすみ。
>>299 わざわざありがとう。
勉強になりました。
shared_ptrは派生クラスのポインタに変換してdeleteしてんのかなぁ。
shared_ptr側から見れば型は明確なんだから、別にすごいわけでもないような??と横レス
基底→派生 だけなら型は明確だけど 基底→派生1→派生2 の時、shared_ptr は派生1のデストラクタも呼んでくれるのかな
派生2であることさえわかっているならふつうに呼ばれそうに思う。 基底 *p = new 派生2 派生2 *p2 = (派生2 *)p delete p2 と同じことというか。 shared_ptrどころかC++の知識が怪しいので、おかしい点があるかもしれないです。
まあそうなんだけど、 コロンブスの卵的な気がするが。
>>306 え? 電話番号を読みこんでいるんじゃないんですか?
>>307 非常に寝ぼけてました、すみません
無くても電話欄も表示されてたから良いかとおもったら名前欄と同じものが反映されてただけでした・・・
某社から供給されたとあるライブラリに コンストラクタがprivateに設定されていてfriendも無いクラスあるんですが、 こういうのってどうやって使えばいいんですか?
310 :
デフォルトの名無しさん :2009/06/27(土) 09:44:41
GUIだけJavaでその他はC++にして 機種に依存しないソフトを作りたいんですけど 作り方の参考になるものを教えてください。
>>309 staticなファクトリメソッドがあるとか。
>>310 その場合、勿論依存しない、ってのはソースコードレベルの話しだよね?
JNI で組め。 そんで環境ごとにライブラリ部分(dll、so)をコンパイル汁
「template 付きの namespace」 的クラスじゃねーの?
template <typename T> class Container { public: typedef std::list<T> list; typedef std::vector<T> vector; // 〜 }; このtypedefつかったテクニックって一般的な名前はあるの?
概念もクソも無い記述上の工夫、設計技量だから名前なんて必要ねえ
staticなメンバ変数にvectorを使った場合、 うまくコンパイルできないのですが、 コンストラクタで初期化が必要とか、何かおまじないが必要なのでしょうか? class Node [ public: static std::vector<int> m_idlist; int addIdList(int id); }; int Node::addIdList(int id) { m_idlist.push_back(id); return 0; }
>>318 vectorとか関係なく、static変数の定義も別に必要なのはOK?
vector<int> Node::m_idlist;
おなじない、って言う考え方は害悪
>>319 変数の再定義になっていまうので、うまくできません。
>>320 そんな深い意味があって書いたわけじゃないんですが、
もちろん、その理由も明確にしたいと思ってます。
>>318 コンパイルはできるけどリンクができないって話なら
cppにstd::vector<int> Node::m_idlist;を追加したらどうだろうか
>>322 できました。
そうか、クラスがいつ作られるかわからないから、
実体を外で作ってあげないといけないんですね。
ありがとうございました。
今読み返したら
>>319 に書いてある orz
コンパイルできないならclass Node "["が原因だと思う
namespace って作ったクラスとかにはもれなく付けるほうがいいの? クライアント側のコードが::だらけですごい不快なんだけど
スコープ解決演算子が可読性を損なうようなほどなら、適切に using namespace すればいいし。 不快とか言う事と、名前の衝突の問題を同列にするのか あと、付けた方がいいかなんて話を疑問に思ってしまうって事は、 多分OO的な集合のイメージを持ってないって事か
class hoge { public: hoge(std::size_t n); private: std::vector v; }; hoge::hoge(std::size_t n) : v(n) {〜;} v(n)は中でメモリの動的確保をしてるはずなのでtryしたいです この初期化方法ではどうやって例外を使うんでしょうか?
FileException::FileException(const char* error) try : m_error(error) { } catch (const bad_alloc& e) { ... } だってさ。普通は外に投げて、つまり、hogeの構築の失敗とみなして hogeを構築しようとしているクライアントがこれを処理するようにする。
ありがとうございます vectorが配列を再確保したときに例外を投げた場合の流れは vector<T>の中でnew[] bad_alloc (Tのデフォルトコンストラクタは呼ばれない) ↓ vector<T>の中で元の配列をdelete[] ↓ throw; という感じでいいんでしょうか? STLと例外の扱いって難しいですね
どうやったら美しいコードが書ける様になれるんだろう
ぐちゃぐちゃな性格のおれには無理だな
インスタンス化禁止にするにはこれで十分でしょうか? class non_instance { private: non_instance(); }; class hoge : private non_instance { public: static void fuga(); };
C++の上級者の人はどんなプログラムの本を買いましたか?
上級者は本を書くんだよ
初心者を中級者に出来る本は?
EffectiveC++
中級者ってどのへんだよ おれ的には、EffectiveC++を読んで楽しめたら中級だと思う
俺的には 入門者,初心者,中級者,上級者 として ・『Effective C++』の内容を読むことはできる。 ・『Effective C++』の内容をまだ理解していない 程度なら 初心者かなぁ。 中級者を名乗るヤツが『Effective C++』の内容すら知ってなかったら もぐり。
質問です。 下のプログラムでポインタを通してconst intの値を変更しようとしたが 変更は無視されました。そういう物なのですか? #include <iostream> int main() { const int I = 123; int* ip = const_cast<int*>(&I); std::cout << I << std::endl; *ip = 234; std::cout << I << std::endl; }
>>344 未定義の動作です。
解説したいのだが、予備知識として問いたい。
「未定義の動作」って意味知ってる?
>>346 そう。それ。
ということは
const int I = 123;
int* ip = const_cast<int*>(&I);
*ip = 234;
が未定義動作なのだから、
「コンパイラーはいかなる動作をするバイナリを吐いても良い。」
ってことになるのは分かる?
値が変わらないどころか
君の鼻から悪魔が出てきてもおかしくないじゃない。
ちなみに現実にはコンパイラは const int I = 123; これによりIが定数であるとして 以下の様なバイナリを吐いたと思われる。 std::cout << I << std::endl; の部分が std::cout << 123 << std::endl; そして*ip = 234;の部分は謎のところの値を書き換え。 だから変わらないのだろう。
c++でパイプってどうやって使うの?
>>349 OSによる
UNIXならソケット
Windowsなら名前付きパイプ
>>347 使用者の鼻から悪魔を出すコード書いてくださいな
>>352 以前書いたのを実行したヤツが死亡したという話を聞いた。
だから俺はもう過ちを犯さない。
hana = CreateHana(); hana.CreateAkuma(); hana.Call( "ジャイアン" );
ジャイアンは耳から出て来る方が恐いお
なんの話してんだよww
Battle( char *a, char *b, char *c ); int main() { Battle( "ジャイアン", "vs", "スネ汚" ); return -032; }
悪魔はミギー
>>358 >>1 乙であったな。
/|
//||
|| /( (・゚))
. |:| //
. | | | | |
| | |. | .||
| | / | , _____ .||
| | / | / ____ / .||
| | /. | / / / / |:|
| || | -‐-| / / / / | |
| ||\ / / / / | |____/ .|
| :| \ \/ | / / \.______/
| | \ ゝノ /
| | /) /
. .|| / / |
| (_/ \
/ /⌒\ \
(___/ \__)
未定義の動作と、環境(コンパイラ?)によって異なる動作というのが わりとごっちゃになる
>>360 未定義の動作と処理系定義のことかな?
未定義の動作ってのは
「動いても何が起こるかも起こらないかも分からない、鼻から悪魔が出て来るかもよ」
例:
>>344 処理系定義の動作ってのは
「コンパイラによって好き放題な結果にしてよいが、動くことは保証されている」
例:
const char const *p="hoge", *q="hoge";
if(p==q){}
362 :
361 :2009/06/28(日) 20:17:24
誤操作した。 if(p==q){} は次のように書きたかった。 if(p==q){foo();} else{bar();} これでfoo()が呼ばれるかbar()が呼ばれるかは分からないが、 どちらかは呼ばれる。
つまり使う側からすると、 ・未定義の動作 = やめたほうがいい。最悪壊れる事もある。(少なくともメモリ上は既に壊している) ・処理系によって定義の異なる動作 = その処理系ではどういう結果になるかを知った上で、かつ他の処理系に持っていく事が無い (理解と自覚あり)ならば、使っても構わない = 問題は起こらない。(それを使う事自体の是非は置いといて) って感じか
364 :
361 :2009/06/28(日) 20:57:23
>>363 そう。
・未定義の動作
= そもそも動かない。動かないならまだしも悪さをしうる。
・処理系によって定義の異なる動作
= ちゃんと動く。どう動くかは処理系のマニュアル(C/C++のではなく。)を読んでください。
とも書ける。
これはもしかするとdirectX関係の質問なのかもしれませんがよくわからないんでここで・・・ if(FAILED(○○○)){ ・・・条件文・・・} よく↑のようにif文で見かけるFAILEDとはいったいどういったものなんですか? 関数なんですかね?またどういう役割をしているんですか?
エラー検出マクロだろ
>>365 それだけじゃ全然分からないな。
C/C++に無いものは知りません。
DirectXスレいけ。
368 :
デフォルトの名無しさん :2009/06/28(日) 22:42:03
ポインタ関係で悩んでいます。 int f(int **m) な関数に int n[10][10] を渡すとgccでは以下のようなエラーになります。 test.c: In function ‘main’: test.c:9: 警告: passing argument 1 of ‘f’ from incompatible pointer type 逆に、 int g(int m[10][10]) な関数に int **n = new int*[10]; for (int i = 0; i < 10; i++) n= new int[10]; としたnを渡すと以下のようなエラーになります。 test.c: In function ‘main’: test.c:9: 警告: passing argument 1 of ‘g’ from incompatible pointer type 上のn[10][10]と**nは似たようなものだと思うのですが関数に渡すときは別扱い されているように見えます。2つはどうちがうのでしょうか。 何らかの方法で渡す事はできるでしょうか。
369 :
デフォルトの名無しさん :2009/06/28(日) 22:45:44
質問です。 派生クラスのインスタンスのサイズの知りたい のですが計測する方法を教えてください。
>>368 int g(int m[10][10]) この関数の引数は ** 型じゃなくて、 int[10][10] 型
だから型が違うと言われて当たり前な気がする
真偽値を返す関数foo()とbar()があるとき、 if( !(foo()) && !(bar())){〜} と if( !( foo() || bar() ) ){〜} とではどちらが望ましいですか? 可読性やスピードなどで。
>>370 int [10][10]型って、なんだよ。
int g(int (*m)[10])だと思うのは私だけだろうか。
int foo[n][m]が関数の引数として渡されるとポインタに成り下がるから
int (*)[m]になるはずだけど。
>>371 関数の中身によっては、その挙動が異なるわけだが、
その部分は考慮しなくていいの?
>>372 そこが良く混同される所。配列はポインタにならないし、ポインタじゃない。
アドレス値を持ってるだけ。 代入や比較ではアドレス値を代入したり比較したりするけど、
型は違う。 キャストすればいける。 あくまで型は int[10][10]型
375 :
373 :2009/06/28(日) 23:04:28
ごめん、勘違いしてたかもしれん。 >373は無視してくれ。
>>373 foo()とbar()は副作用を持たない関数だと想定しています。
言葉足らずでした。
それ以外では挙動は同じになりますよね。
char型の変数chがあり、chには
'0','1','2','3','4','5','6','7','8','9'
のいずれかの値が入っていることが分かっている。(つまりch.isdigit()がtrue)
このとき、chの中に入っている文字をint型の変数の数字として取得するには
どうするのが一番動作速度が速い?
>>41 などなどで、
数字が連続している事が保証されている
という結論になってるけど、それを踏まえるなら
単純に
static_cast<int>(ch)-static_cast<int>('0')
だろうけど、これ以外に早い方法ないし標準C++ライブラリの関数はある?
>>372 ヒント:
> int g(int (*m)[10])だと思うのは私だけだろうか。
そもそも配列サイズは固定だろ?sizeofで返る結果も違うだろ?
int[10][10] を期待してまっている関数の引数として、例えば int[2][2] の ** を渡して一致すると思うかい?
・・・ってのは逆説的な言い方だけど。
int g(int (*m)[10]) … もしも第一階層が不定サイズの内容を扱いたいなら、
vectorに突っ込んでvectorの参照でも渡しとくといい。
Javaとかだと int g(int[][] m) みたいなインタフェースが成立するけど、C++には無い。 考え方が違う
>>377 なぜキャストするのじゃ。^^
ポインタ同士の引き算の結果はptrdiff_t(ぷんたりでぃっふんてぃー)型であり
それは一般に long int であり、仮に一般的じゃなくても
明治キャストしなくても整数型に変換されるのです。
そしてポインタの演算ほど高速な世界はありません。
>>379 最後の一行は無関係でどうでもいい話だけど、じゃあ何故コンパイラが型違いと言ってエラーにしたと思う?
>>374 そうなんですか。確かにキャストすると実行できました
ふーむ。キャストしないといけないのか。
仮に違うものだとしても暗黙のキャストがされるだろうと考えていたので驚きです。
ありがとうございました。
>>382 俺も昔間違えてたからさ。 暗黙キャストは出来ないんだよ。 添え字違うとサイズも違うから。
int[10][10] が待ってる所に 他の大きさの配列をキャストしたポインタとか来られても困るでしょ
そういうこと。
それはまあいいとしても、なんでキャストしてんの?とは思うね。
きゃすとwwwww 型安全にしような
似たような話が平行すると誰が誰にレスしてんのかわからんww
>>383 おお、よく読んでなかった。すまんすまん^^;;;;;;;
いずれにしてもcastは不要なのじゃ。
ch - '0' で char 型の値が返り、
char は整数型に暗黙に変換できるので
明治キャストは不要なのじゃ^^
すまんこ。
そしてこれはとても速い。atoiとかやってることいっしょ。
(atoiは'-'とか'+'も判定しているみたいだけど)
>>384 なんか、その論調だと
void func(int m[10][10])
void func(int (*m)[10])
では、sizeof(m)の結果が違うかのように読めるんだが
'0'ってintじゃないっけ? だったらch - '0'はintに釣られてintになるんじゃないっけ?ちがった?
391 :
377 :2009/06/28(日) 23:51:21
392 :
377 :2009/06/28(日) 23:53:13
ちなみに static_castを付けたのは、型がどうとかレスが付く気がしたから あらかじめその可能性を排除するつもりだった。 その結果逆にstatic_castへのレスが付いてしまったな。 やっぱ付けるべきじゃなかったか。 惑わしてごめんなさい。
>>389 違う違う。 m が来るかどうかわからない、って事
m のサイズが違うじゃなくて、そのポインタが果たして [10][10]の配列のアドレス(例の場合 m)が
コピーされた物なのかどうか、ポインタになっちまったらわからないって事。
だから安全の為にそういう記述はコンパイルの段階で防がれるって事
[5][10]やら[2][10]なんかは防げないってことを言いたいんじゃねーの?
>371 見やすい方にしておけと言っておく。 どうせコンパイラが最適化してしまい結果同じになるから。
void func(int m[10][10]) void func(int (*m)[10]) で sizeof(m)が同じだからって何なんだろ 等価じゃないのに
お前は何を言ってるんだw
夜更かしするから。。。
>396 どちらも同じシグナルの関数
シグナル……
等価じゃないよ。前者にはポインタが渡せない。
**pはどっちにも渡せないが、(*p)[10]ならどっちにも渡せる。
#include <stdio.h> void foo( int m[10][10] ) { printf( "foo!\n" ); } void bar( int (*m)[10] ) { printf( "bar!\n" ); } int main() { int n[10][10]; int (*p)[10] = n; foo( n ); foo( p ); bar( n ); bar( p ); } わたせるじょ。
void foo( int m[static 10][10] )
またまたオナニーしちゃって そんなことやると移植性が
408 :
デフォルトの名無しさん :2009/06/29(月) 17:22:41
VC2003で、 メインスレッドから渡された情報を メール送信するスレッドを作ったんですが、 メール送信にてメモリリークを起こしていたんですよ。 #define _CRTDBG_MAP_ALLOC とかを使っても原因がわからなくて先にやれること全てやるべきだと、 warningを出していた、strcat,sprintfをCString型を使って 編集することによってwarningを消したところ、 大幅なメモリリークがなくなりました。 多いときでメインスレッドから 1秒間に数回メール送信のスレッドへ情報が渡される状態でしたが、 (メール送信処理は多少時間がかかるので順番待ちしてます) strcatやsprintfがメモリリークの原因になることってあるんですか? ネットで調べてもnewやmallocがメモリリークの原因になるという記述はあっても、 strcatやsprintfがメモリリークの原因になるような記述が見つかりませんでした。
どっか破壊してて、それがリークって判定されたんじゃね?
おまえには無理
413 :
411 :2009/06/29(月) 22:55:17
414 :
411 :2009/06/29(月) 22:58:30
というかテンプレートクラスの定義ってヘッダファイルに書くのが常識なようですね… なにか勘違いしていたようです
415 :
デフォルトの名無しさん :2009/06/29(月) 22:59:24
makefileの改行コードって\nですか?
>>414 ああ、そうじゃないと
undefined referenceになるだろうね。
説明は・・・
誰か頼む、俺は寝なきゃならない。
テンプレートクラスの扱いはコンパイラによってめちゃくちゃなんだよね。 特殊化するとヘッダファイルにかけなくなったりするし。
>>415 お使いのmakeプログラムの仕様をご覧ください。
#include <stdio.h> class A { public: static void PrintA(); void PrintB(); }; class B { public: void PrintB(); }; void A::PrintA() { printf( "A\n" ); } void A::PrintB() { printf( "A-B\n" ); } void B::PrintB() { printf( "B\n" ); }
int main() { A a; B b; A::PrintA(); a.PrintB(); b.PrintB(); return 0; } のように メンバ関数を static にするメリットは何でしょうか?
>>421 ・インスタンス毎に作られるわけではないので極端な話インスタンスが
一個もなくても呼び出せる
・インスタンスがいくつあっても一個しか無いように見えるのでそれを
利用してSingletonなどのデザパタを実現できる
・名前空間の圧迫を避ける ・テンプレートクラスと組み合わせで本領発揮
欠点は利点の裏返しで ・non-staticなメンバ関数はインスタンス毎に作られるように 見えるので他のインスタンスには干渉しないがstaticメンバ関数は すべてのインスタンスから干渉を受ける
メンバ関数なら、そのクラスのprivateメンバにアクセスできる ふつうのグローバルな関数は、クラスのprivateメンバにはアクセスできない
Windows visual studio2005 で作ったC++の.exeからソースファイルを見たいんだが・・・・・そういった類のソフトやツールはないかなぁ
きもいです
きもすいです。
想像してごらん 輪切りのピーマンにウィンナーを通してるところを pi-man = Create( "ピーマン" ); winner = Create( "ウィンナー" ); Wagiri( &pi-man ); pi-man.Insert( winner );
なんだよ、パイマンってw
C++でC言語は扱えますか?
無論じゃ
YESでありNOでもある。 >436が使う程度ならYES。 テストで出てきたらNOかもしれない。
>>426 C++のexe ってなんだよ。コンパイルしたらマシンネイティブだボケ
ツールもへったくれも、中間言語形式でもない限り、ソースの姿になんか戻せる訳無いだろ
※機械語ニモニック除く
C/C++の最適化をOFF(デバッグモード)にしてコンパイルすると 結構な所まで戻るよ リリースモード(最適化最大)にすると元のソースの姿はまずほとんど 残らないと思っていい
441 :
デフォルトの名無しさん :2009/06/30(火) 22:20:08
vc2003で作成したexeを起動して、ある程度の時間起動していると、下記のエラーが発生して止まってしまいます。 中断をしても混合モードで表示されるのでソース上の位置が特定できません。 test.exe の 0x0746398c で初回の例外が発生しました : 0xC0000005: 場所 0x00000256 を読み込み中にアクセス違反が発生しました。 。 test.exe の 0x0746398c でハンドルされていない例外が発生しました : 0xC0000005: 場所 0x00000256 を読み込み中にアクセス違反が発生しました。 。 場所は 0x00000256,0x0000023a, 0x00000266などと特定されてないんですが、 0x0746398c が固定なんですよね。 メモリのアクセス違反なんでしょうが、0x0746398cを実行している箇所を特定する方法を教えてください。 もしくは、混合モードで表示されない設定方法を書いてあるサイトへ誘導していただけないでしょうか。
link時にmapファイルを出力してみれば?
動的配列の要素数を、中身を保持したまま増やすにはどうすればよいでしょうか VBAでいうとReDim Preserveに当ります
>>443 (1) 最初から領域をいっぱい確保して、その中におさまるよう期待する
(2) それより増えたら、しょうがないので新しく領域を確保して古いのをコピー
vectorなどに任せる
「動的配列」、「中身を保持したまま領域を増やす」 みたいな 高級な概念(人間の都合による動作)はC/C++には無いので、用意した領域を使い、それで足りないなら サイズの大きな新しい領域を用意してそこにコピーして処理を継続する、ってやる他無い。 vectorなどのライブラリを使えば、その辺の実装を隠して実現してくれるので 面倒ならそれらを使うといい。
reallocで代用は邪道かな WindowsならHeapRealloc等で再割り当ても出来るけどやっぱり邪道かな
>>441 それは、メモリにロードされたtest.exeのマシン語のまさに実行しようとした番地だろ
デバッガで実行すれば、特定してくれるよ
"場所 0x00000256"辺りは、OSにもよるが、どう考えてもOS管轄の触れるな危険領域
内容的には、初期化していないポインタの間接参照だな
>>448 Cならrealloc。
ここらへんは、質問にCかC++か書いてくれないと。
アドレスを渡すべき関数に値を渡してるのかなー
未初期化のポインタを渡していると見た。
453 :
デフォルトの名無しさん :2009/07/01(水) 09:55:49
while(b) とはどういう意味でしょうか? ifの場合は if(a!=0)=if(a) なので、while(b!=0)と同じ意味ととらえていいでしょうか?
仕様とかよくわからんけどwhile((bool)b)じゃないかな
いいえ、b != 0です。
456 :
デフォルトの名無しさん :2009/07/01(水) 11:46:11
457 :
デフォルトの名無しさん :2009/07/01(水) 13:07:09
UTF-8環境で、 何かの型 str = "山a川"; cout << str[0] << endl; // 山 cout << str[1] << endl; // a cout << str[2] << endl; // 川 となるような方法って無いでしょうか?
>>457 Unicodeに変換して
wcout << wstr[0] << endl; //山
wcout << wstr[1] << endl; //a
wcout << wstr[2] << endl; //川
operator[] を用意して ビット列 10xxxxxx を除いてカウントアップすればいい。
いまどきSJISべったりはやめようぜ
462 :
461 :2009/07/01(水) 19:36:52
ああ、すまん、思いっきり誤読していた
out_of_rangeとrange_errorってどう使い分けるんだ?
464 :
デフォルトの名無しさん :2009/07/02(木) 01:05:33
プログラミングのスタイルについて質問させていただきます まず、以下の二つのAとBのコードをごらんください。 ■ パターンA int hoge(int data) { if (data == 0) { return 0; } data = data + 1; return data; } ■ パターンB int hoge(int data) { int ret; if (data == 0) { ret = 0; } else { ret = data + 1; } return ret; }
(続き) 私の会社のコードレビューで意見が衝突しているのですが、 パターンAの場合、コードが見やすくて良い意見と、 returnが何回も書いてあるのは見づらいという意見があります。 パターンBの場合、最後だけreturnがあるのでコードが追いやすいと意見はあります。 一般的にはどちらが良いのでしょうか? 理由も合わせてご教示お願いします。
>>464 昔、10年前に目立ちにいたものだが、パターンAでプログラミングしたものを上司にだしたら、
わかりにくいからパターンBで修正しろと怒られた。
でも、最近の若い人は圧倒的にパターンAで書く人が多いね。
俺は、パターンBで書くことが多い。
>>465 宗教の問題。 関数の途中にreturnを入れないという宗派が存在することは確か。
個人的には、そのコードぐらいreturnするしないの条件が単純ならやってもいいと思う。
論点になるのは、処理の追いやすさとか、
関数途中でエラーが出たときのリソース解放のしやすさとか。
誰かに強制されている状況でない限り、自分の好きにすればいいと思うよ。
俺なら int hoge(int data) { if(data) data++; return data; } int hoge(int data) { return data ? data + 1 : 0; } のどっちかだな。
戻り値が必要な関数には少なくともひとつのreturn文が必要なわけだけど 古いC++コンパイラには、if文の中のreturn文を調べないスカポンタンな代物があったんですよ。 それで、できる限りreturn文は関数の末尾にまとめようよみたいな習慣があったです。 しかし、いまどきそんなあふぉーなコンパイラはありませんので、 今はパターンAを使います。 理由は簡単。464のコードは単純だからいいですが、 もし仮に関数hogeの引数が10億ペタバイトを必要とする巨大オブジェクトをコピーするようなものであったとき、 あるいは、関数hogeが1日に1000兆回も呼び出されたりするようなとても重要な関数だった場合、 パターンBはオブジェクトが1つ多い分だけ、コストが膨大になるからです。 何かの拍子にこの関数が参照渡しに書き換えられたときのコストも考えてみましょう。 っていうか、そんな細かい話でぶつかってるクソプロジェクトは 間違いなく火の海です。
関数の内容によって2つのパターン併用するのが自然なのでは。 どちらかに決めるともう一方のパターンで書けば もっとシンプルにできるケースまで強制されるハメになる。
前者はアルゴリズムの枝狩りの感覚に似てるよね。 この場合はとっとと終わるっていうのが明確でいい。 インデントも深くならないし。 後者のメリットは関数を抜ける場所が一つになることで、free忘れが 減ったりするんだろうけど、実際そのスタイルにすることで、そういう 恩恵を得られたという実感はないね。 戻り値用の変数をずーっと持っておかないといけないのもイマイチ。 というのが、個人的な意見です。
>>468 コーディングスタイルのハナシっすから。
C++ Coding Standardsにはずばり、 関数にはひとつの入り口とひとつの出口という発想は デストラクタや例外といった機構を持つ言語では 時代遅れとしかいいようがないと書かれている。
例外機能でまかなえるからこそ有効値内の処理はフローを整えるべき
476 :
デフォルトの名無しさん :2009/07/02(木) 07:23:48
基本的な質問で恐縮なのですが・・・ C++で、staticなメンバを含まないクラスを記述する時、そのクラスのコードは ヘッダファイルに記述するべきなのか、ソースファイルに記述するべきなのか、どちらなんでしょうか。 class A { public: int get();
477 :
476 :2009/07/02(木) 07:25:35
途中で書き込んでしまいました、すみません。 // *.h class A { public: int get(); }; // *.cpp Aint A::get() { return 1; } か、 // *.h のみ class A { public: int get() { return 1; } }; か
478 :
477 :2009/07/02(木) 07:26:43
Aint はtypo。 度々すみません
>>464 その例のようにフラグ変数を追加してまで固執するのは
賛否あるけど、一般的にはBの方がいい
出口を複数作るのはよくない。
効率ならA 老害対策にはB 可読性は個人の感覚しだいで甲乙つかず といったところか
481 :
デフォルトの名無しさん :2009/07/02(木) 08:25:16
>>464-465 パターンBは、初心者に教えるときに向いている。
ifとelseが対等だから、それぞれの場合を考えやすい。
パターンAは、ifでやろうとしていることが例外的なことならスマート。
無駄な一時変数も要らない。
しかし、こうなるとちょっとキモイ。
■ パターンA’
int hoge(int data)
{
if (data != 0) {
return data + 1;
}
return 0
}
それに対して、こっちはいたって自然。
■ パターンB’
int hoge(int data) {
int ret;
if (data != 0) {
ret = data + 1;
} else {
ret = 0;
}
return ret;
}
■ パターンC int hoge(int data) { if (data == 0) { return 0; } else { return data + 1; } }
僕は、 int hoge(int data) {return data + !!data;}
>>476 の質問はこのまま埋もれて消えるんでしょうか・・
>>476 インライン展開を望むならヘッダ中。
そうでなけりゃ、基本ソース中。
>>485 ありがとうございます、すみません。
その場合、何か動作上の違いというのはあるんでしょうか
淫乱展開すると関数呼び出しのオーバーヘッドがないから超高速。 一方で、関数としてまとめられることがないのでコードの増大を招く。 そしてもうひとつの問題が。 inline キーワードを使おうと、クラス定義に直接コードを書こうと、 本当に淫乱展開するかはコンパイラしだい。
>>487 なるほど・・・ つまり、
// どちらも *.h で定義
class A { public: int get() { return 1; } };
// ソース側で定義。Aと同内容
class B { public: int get(); };
とした場合、Bのインスタンスに対して
B b;
b.get(); ← このタイミングで暗黙の内に関数名と実際のアドレスの解決が行われて、ジャンプしてそこで処理される
って事なんですね。オーバヘッドと仰ったのはそのジャンプ(関数呼び出し)の部分
具体的に機械語レベルでどう落とされるかは、コンパイラの実装次第
>>487 > 淫乱展開
( ) ジブンヲ・・・・・・
( )
| |
ヽ('A`)ノ トキハナテ!
( )
ノω|
__[警]
( ) ('A`)
( )Vノ )
| | | |
■パターン4 int hoge(int data) { return (data != 0)? data + 1: data; /* あえて ++data と書かない */ }
子供が多いな まだ夏休みには早いだろ? 宿題でもやってろよ
493 :
デフォルトの名無しさん :2009/07/02(木) 18:05:02
質問させてください。C言語です。 ボックスミュラー変換で正規分布のdouble型の乱数Aを作成するプログラムを作ったんですが、 それを(正規分布の特性を失わずに)整数値としてあつかいたい場合(何かの得点として扱いたい場合)は、 int型でキャストすべきなのか小数点以下を四捨五入するべきなのか教えてください。 r1=rand()/RAND_MAX r2=rand()/RAND_MAX A=sigma*sqrt(-2*log(r1))*cos(2*PI*r2)+m; sigmaは標準偏差でmは平均です。
>>493 これ、C言語の質問じゃなくてアルゴリズム(と言うか、考え方)の質問じゃね?
話こんがらがったか
言語の質問って範疇で言うと、元々doubleで持ってる値をintに丸めたら、
どうしたって精度的は下がる訳だから決め打ちでいいと思う。
考え方の質問って事ならスレチかもしれないが、偏りに応じてオフセット付けて、n捨m入にして
丸めればいいと思う。
495 :
デフォルトの名無しさん :2009/07/02(木) 19:23:19
以下のように使用しているifstreamに #をコメントアウトとしてスキップ機能を追加したtmpifstreamクラスを作って ifstream file_input; int n; file_input >> n; tmpifstream file_input; のように(コードの大きな修正なく)代替したいのですが、 下のクラスのoperator >> ()のところのメンバ関数をどのように書けば良いか 教えていただけないでしょうか?すみません。よろしくお願いします。 class tmpifstream{ public: newfstream(){} ~newfstream(){} operator >> (){ /* ← ここです */ file_input >> buffer; /* bufferの先頭に#を含むかの判定 */ /* その後の処理も分かりません。。 */ } void open(){/* file_inputを開く */} void close(){/* file_inputを閉じる */} private: std::ifstream file_input; std::string buffer; }
>>481 パターンBは理解しやすいかもしれないが
初心者に教えたらデカいクラスでも同じことやりそうで怖い
どゆこと? 演算子のオーバーロードをどう記述していいかわからないってこと?
>>495 ifstreamではなくstreambufをカスタマイズするべきだと思う
GPLライセンスとはなんでしょうか? GPLに関する記事を他のサイトで見たのですが、その事もよく理解できません。 GPLと、GPLライセンスについて教えてください。
501 :
495 :2009/07/02(木) 20:52:59
>>497 そうです。
どう書いたら、目的が果たせるのかちょっと分からなかったので。
>>498 ありがとうございます。できましたら、簡単なサンプルをお願いできないでしょうか・・
503 :
デフォルトの名無しさん :2009/07/02(木) 23:36:23
>>502 ありがとうございます。
しかし、かなり難しい話になるんですね。
505 :
デフォルトの名無しさん :2009/07/03(金) 22:47:06
class Base{ public: void hoge(int i); }; class Sub : public Base{ public: void hoge(double d); }; のようにBaseのメソッドをオーバーロードした場合、SubのインスタンスからBaseのhogeって呼べないんですか? コンパイルエラー出るみたいで。 後、解決方法は class Sub : public Base{ public: void hoge(double d); void hoge(int i){ Base::hoge(i); } }; 以外に何かありますか?
CHoge::CHoge(){m_pCFuga = new CFuga;} try{CHoge *p = new CHoge [n];}catch(...){/*〜〜*/;} とすると @sizeof(CHoge)*xのrawMemoryを確保 A0〜n-1番目の要素にデフォルトコンストラクタを呼ぶ Bpにアドレスを代入 という流れになると思うんですけど@あるいはAの段階でbad_allocが投げられた場合 それぞれどういった挙動を示すんでしょうか? @でbad_allocが出た場合は巻き戻されてメモリ確保がなかったことに Aでbad_allocが出た場合は呼ばれた分だけデストラクタ→rawMemoryも解放 と、ここまで自動でやってくれるんでしょうか?
>>505 呼べないよ。解決方法はそれか、using使うぐらいかな。
class Sub : public Base{
public:
void hoge(double d);
using Base::hoge;
};
>>505 Sub s;
int x;
s.Base::hoge( x );
のような呼び出し方はできる。
でも、s.hoge(x)で呼びたいなら、
あなたの示した解決法しかない。
基底クラスと派生クラスで同名の関数があるとき
(それらの戻り値や引数がことなり、本来別の関数として認識されるものであっても)
派生クラスのオブジェクトでは
基底クラスの関数は派生クラスの同名関数によって「すべて」隠蔽される。
関数がvirtualであるかどうかも問題にならない。
510 :
505 :2009/07/03(金) 23:58:02
>>507 , 508, 509
同一クラス内でのオーバーロードは予想した通り(変数の型で呼び出すメンバを変更する)に動いたので、継承でも同じように動作すると期待していたのですが・・・
継承ではそういう動作をしないのですね。分かりました。
解決方法は、usingの使用がスマートな感じがするので、これでいきたいと思います。
返答ありがとうございました。
Baseいじれて多少ダルイ事になってもいいならダミーのデフォルト引数付けるようにすればいいんじゃないかな
class Base{ protected: int A; Base(){ //Aを使った動作 } } Class Sub : public Base{ public: Sub(){ A = 10; } } こんな感じで、派生したオブジェクト作成と同時に、Aに派生先固有の値をいれ、使おうとしたら Baseのコンストラクタ → Subのコンストラクタ の順で呼び出されてしまい、Aの値が不定になり意図した動作ができませんでした。 Baseの動作をSubにそのまま組み込むことも一応できるのですが、それだとわりと長くなってしまうため… 何かスマートな解決法はないでしょうか
class Base{ protected: int A; Base(){} Func(){ //Aを使った動作 } } Class Sub : public Base{ public: Sub(){ A = 10; Func() } } じゃだめなの?
もちろんそれで動くし、それで進めることも可能なのですが かなり派生する数が膨大で、1個1個のコンストラクタに記述するのも大変なので…。 ほかにいい方法がないかな、と思い相談させていただきました。
すみません、たしかに質問の内容が足りていませんでした…。
513は自演だと思う。 幼稚園スレといえどもイキナリ二匹も現れんでしょ
Aをstaticにして、Aの定義をSub側で行うのはどう?
519 :
518 :2009/07/04(土) 02:04:00
わ、わすれてくださいorz
>>512 こんなのは?
class B {
protected:
int A;
B(int n) : A(n) { /* Aを使った動作 */ }
};
class D : public B {
public:
D(): B(10) {}
};
と思ったけど、なんか難しく考えすぎた。
>>513 でいいじゃん。
521 :
513 :2009/07/04(土) 02:17:05
class Base{
protected:
int A;
Base(){}
Func(int a){
A = a;
//Aを使った動作
}
}
Class Sub : public Base{
public:
Sub(){
Func(10);
}
}
あんまり詳しくなくてこんなんしか思いつかないや。ごめん。
>>517 自演?
522 :
512 :2009/07/04(土) 02:40:46
うーん、やっぱり、Baseコンストラクタ内での処理はあきらめたほうがいいのでしょうか。 複数回呼び出すとまずい処理だったので、できればコンストラクタ内で収めたかったのですが… とりあえず、Baseコンストラクタ内の処理を移して改めて呼び出す方向でいってみたいと思います。 ありがとうございました。
>>522 なるほど、それだと初期化関数Func()を派生クラスから呼べるようにはしたくないな
だったら
>>520 みたいのは?
>>520 みたいなことできるの初めて知った
結構びっくりしてる
525 :
512 :2009/07/04(土) 03:24:01
>>520 知らない記述方法だったので、最初見たとき理解できてませんでしたが
改めて見直すと… ちょっと、いろいろと試してみます。
ええと、この場合、10の値を外部からもってくるとか、計算で求めることもできるんでしょうか?
526 :
512 :2009/07/04(土) 03:47:26
なるほど… 自己解決しました。 D(): B(10) {} の部分を D(int nan): B(nan) {} とかに変えると、引数を持ってきたりも可能ですし、B(nan)の中で計算も可能みたいですね。 これで解決しそうです。 本当にありがとうございました。
毎レス情報を増やすというのを最後まで一貫してやり遂げたのはすごいな
nanはナンバーのつもりならnumにしたほうがいい nanは誤解される
全然関係無いけど、変数名 nan だと、NotANumberに見えてしまう罠 さて、明日の昼はナンでも食べるか
ナ、ナンダtt
531 :
512 :2009/07/04(土) 04:45:35
>>527 読み返してみると、確かに酷い質問の仕方でした…
次から注意します。
>>528-529 最近、学生時代英語サボっていたことをものすごく後悔しています…
それにしてもnanはないだろww
class Base { int A; Base( int a ) : A(a) { /* Aを使った処理 */ } }; class Derived : public Base { static int a = 10; Derived() : Base( a ) { } }; まぁ、質問の意図がよくわからんから、いいや。
UTF8で書かれたテキストファイルをstringに読み込むにはどうすればいいんでしょうか?
a->b これってどういう意味でしょうか?
aの先のb
Hoge h; std::cout << h << std::endl; こうやってhの情報(例えばメンバ変数など)を表示させたいのですが どうやればいいのでしょうか? <<演算子を定義するのでしょうか?? キーワードだけでもお願いします。
operator<<(fstream&, const Hoge&)
ostream& operator << ( ostream& os, const Hoge& h ) { os << h.member_; return os; }
540 :
537 :2009/07/04(土) 16:11:22
ありがとうございます これを手がかりに色々調べてみます
#include <iostream> using namespace std; class test { public: test(int x) try : p(new int [x]) {cout << "test" << endl;} catch(bad_alloc& e) {cout << "err test: " << e.what() << endl;} ~test() {delete [] p; cout << "~test" << endl;} private: int *p; }; int main(void) { try { test t(-10); } catch(bad_alloc& e) { cout << "err main: " << e.what() << endl; } return 0; } 出力結果 err test: bad allocation err main: bad allocation test()でbad_alloc例外をもみ消したはずなのに、main()で例外を補足してしまうのはなぜでしょうか?
コンストラクタだから。
shared_ptrに配列わたしたいときって void satsugai(CFoo* aFoo) {delete [] aFoo;}; shared_ptr<CFoo> saFoo(new CHoge [num], satsugai); ってやるのが一番スタンダードなの?
>>544 インデントが全角になってるからそのままじゃコピペじゃできない
    test
全角インデントにも気づかないコピペ厨
まあ気づかないヤツもダメだけど、全角インデント使うヤツもアホだろ。
>>545 >>546 お前ら低脳か
全角がちゃんと□と表示されるエディタ使ってるわい
コンストラクタの所で
エラー E2040 constructor1.cpp 7: 宣言が正しく終了していない
というエラーが出るんだよ
コンパイラはCodeGear C++ 6.1.3(最新版)
>>535 アロー演算子。
MyClass hoge;
hoge.foo();
に対して、
MyClass *p=new MyClass();
p->foo();
の様に使う。
>>541 function try blockといって、throw;しなくても例外が再送出されることになってる。
ことコンストラクタに関しては例外をもみ消したところで
無効なオブジェクトがのこるだけだから意味がない
C++のSTLのpriority_queueで構造体を扱いたいのですが、 typedef struct{ char name; int age; bool sex; }human; priority_queue<human> pq; とした場合構造体のageで並べ替えたい場合はどのようにすれば良いのでしょうか?
human同士を直接比較できるようにすればいい operator<()を定義するのが簡単じゃないかな bool operator<(human& a, human& b) { return b.age < a.age; }
>>553 constが必要だろ
bool operator<(const human& a, const human& b) {
return b.age < a.age;
}
template classの実装を隠蔽する(ヘッダとソースに分離する)方法はないの? 特殊化したclassなら隠蔽できることまではわかったんだけど・・・なんかいいテクは無いものかな
そしてお前はexportを調べてガッカリする
558 :
552 :2009/07/05(日) 16:35:53
>557 最新のVSでもダメらしいね…
何でexportって実装されないの?
面倒だから
演算子の日本語っぽい読み方ですが、 +は加算、ーは減算 ++は、まぁインクリメントで妥協するとして +=はなんと表現すればよいでしょうか?
加算代入 たすわー
++プラプラ たすイコール
アッド
+プラス ++プラプラ +=プラスイコール
日本語っぽい読み方 って書いているのに英語っぽい読み方している人たちは 帰化人ですか?
和製英語だと言いたいのでしょう
どうみても日本語だな
いえ、奇械人です。
+たす ++たすたす、いんくり、まえいんくり、あといんくり +=たすわ、たすいこーる
+ぷらす ++ぷらぷら +=ぷらすいこおる
加算代入が良さげですね、例え造語でも。 いあ、しょーもない話、operatorのオーバーロードのコメント書いてて なんてかきゃいいのか詰まったもんで ほんとどーでもいいはなしで、さーせん
造語じゃなくて文で書けよ
俺の場合 /** * オペレータを足し入れる */
577 :
576 :2009/07/06(月) 01:46:31
オペレータじゃなくてオペランド 素だった・・・ もう寝る
/** * 加算演算子のオーバーロード */ 俺はこのコメントを見て、そしてそっと削除した
/** * 経理のあの子に入れて出したい */
string str[10]={"aaa","bbb"・・・・}; にように配列を決めて、 cinで入力した文字列とif文で等号を調べます if(ch==str[0]) {} else if(ch==str[1]) {} のようにして、最後に elseとして合致しない場合のパターンもつけたいのですがうまくいきません。 なぜでしょうか?
どううまくいかないのかかいてください
>>580 「うまくいかない」では分かりません。
どう「うまくいかない」のか、
これを明確に書いてください
もうテンプレニイレヨウぜ、こういうやからが多すぎる。
相手しない、という選択肢はダメですか?
584 :
580 :2009/07/06(月) 22:47:42
すいません。 どんな文字列を突っ込んでもelseifの方になってしまい、elseになってくれません
何を言ってるのかわからん。「elseになってくれません」のelseって、このコードのどこだ? あとchの型は? 何をどうしたら、こんなに説明下手になるんだ・・・電話の向こうの人にジェスチャーで物事を伝えるレベル。
>>580 chが本当に文字列ならstrcmpを使って比較
>>584 本当にあらゆる文字列を試した?
どれか一つくらい else の方にいくはずだよ
chがstring型だとして、どんな文字列を入れても(ch==str[1])が真になっているということか。 可能性1 ch = str[1]; if(ch==str[0]) {} ... 可能性2 if(ch==str[0]) {} else if(ch=str[1]) ... どっちかだとおもうんだけど。
constしたクラスを使うには、一度別にキャストしないと駄目かな? const指定したクラスのメソッドを使うと、thisポインタがなんちゃらってエラーが発生する
なんちゃらすれば解決
そのなんちゃらがconst this&に変換出来ないって内容だった気がする
>>589 説明が下手なんだから、実例を挙げなさいよ。
>>580 あんたもコンパイルできて再現する最小のコードを挙げなさいな。
きさま、Java厨だな!
const CHoge *getHoge( ) { return &g_cHoge; } const CHoge *pHoge = getHoge( ); pHoge->hogehoge( ); // ここでビルドエラー
>>594 どうせhogehoge()がconstメンバになっていないんだろ。
constぐらいググれ。 つーかいかなる本にでも書いてあるだろ。
int **p; const int **q = p; がエラーになるのはなぜ?
>>597 型が違うから。
前者はintへのポインタのポインタで、後者はconst intへのポインタのポインタ。
int * pp;
const int * qq = pp;
なら通るけど、const intへのポインタにintへのポインタを代入する際にはconstをひとつ被せるだけの暗黙の型変換が行なわれている。
従って、
int ** p;
const int ** q;
q[0] = p[0];
ならコンパイルは通る。
# が、勿論正しくない。
>>594 const CHoge *getHoge( ) const { return &g_cHoge; }
>>598 constを付加する暗黙の変換は
間接参照レベルが2以上になると効かないってことでいいのでしょうか。
一応、それを実証するべく
int a;
const int *p = &a;
const int **q = &p;
ってやったら、なるほど、エラー出ませんでした。
const int * const *q ってやれば一度で行くんじゃないか? 要するに暗黙変換は一度に一個しかconstを付けないよ、って事だろうな 規格票のどっかに書いてあると思うけど
>>597 const int を int const に置き換えて (両者は同じ)、
T *p → T const *q って考えるといいよ
良い例
int *p → int const *q (T=int)
int **p → int *const *q (T=int*)
int const **p → int const *const *q (T=int const*)
ダメな例
int **p (T = int*) → int const **q (T = ?)
int **p (T = int*) → int const *const *q (T = int const*)
>>599 getHogeじゃなくてhogehogeをそうしないと。
605 :
デフォルトの名無しさん :2009/07/07(火) 15:31:39
3ケタの数字をランダムに被りなしで表示したいのですが、よくわかりません。よろしくお願いします。
3桁の数字を全部生成してシャッフルしろ
#include <stdio.h> #include <stdlib.h> #include <time.h> enum { N = 1000 }; int main(void) { int a[N], i; for(i = 0; i < N; ++i) a[i] = i; srand((unsigned)time(NULL)); for(i = 0; i < N-1; ++i) { int t = a[i], r = rand()%(N-i)+i; a[i] = a[r]; a[r] = t; } for(i = 0; i < N; ++i) printf("%3d%c", a[i], (i+1)%5?' ':'\n'); return 0; }
608 :
デフォルトの名無しさん :2009/07/07(火) 18:52:16
gccでOSのマクロ定義が書かれているヘッダファイルって どこにありますか?
定義済みマクロだろ
>>608 find / -name '*.h'|xargs grep __YourOS__ | grep -w define
デモ実際は>609だと思われ。
昔は gcc -dumpspecs で見られた気がするけど、いまは無いみたいだね。
"_hoge", referenced from: _hoge$non_lazy_ptr in hogehoge.o symbol(s) not found collect2: ld returned 1 exit status ってリンクエラーはどうすりゃ解決できるのだろうか
hoge の実態があるオブジェクトをリンクする
動画再生ソフトでがバーをドラッグするとその時間から再生できるのがほとんどですが 再生が始まるポイントが絶対決まってると思うのですが、つまり4秒くらいのところにドラッグしても絶対2秒から始まるような これは何故でしょうか?
板違いです
616 :
デフォルトの名無しさん :2009/07/08(水) 08:32:23
じゃあどこで聞けばいいのよ?
>>616 板もそうだが、少なくともスレタイとは思いっきり無関係。
あえて強引に答えるとするなら、再生可能位置のアドレステーブルとかを持ってるような構造で作られてて、
バーを100%とした中でのxの位置からアドレステーブルの該当箇所をとりだして、そこを ** で拾って表示してるとかじゃないかな
他人が作ったなんらかのソースも無いアプリケーションの挙動について、全部想像で返答
618 :
デフォルトの名無しさん :2009/07/08(水) 09:05:29
時間方向の情報を基に圧縮をかけると途中から再生が出来なくなるけど、 時間方向の情報を基に圧縮されていないデータが挟まれていればそこから 再生できるようになるのでは?
>>614 ぜんっっっぜん
スレ違い。
さよーなら、おまぬけさん。
サイコロ振って決めたとか、そのレベルの適当な理由がないと、 このスレで質問しようと思った経緯が理解しがたいよな。
プログラム暦1年くらいで動画再生の方法とかはまだ知らないレベルで DirectXサウンドの存在は知ってるレベルだからまあC言語スレかなと思いますた
>>614 キーフレームの途中からなら、すぐに再生できないのが当たり前。
これ以上は…どこだろ。DTV板かなあ。
キーフレームって数秒おきじゃなくてもっと細かいのかとおもってた。
圧縮時に決められるコーデックが多い。 基本はフレーム単位で指定するけど 1時間単位みたいなことにできるものもある。
スレチだけど勉強になった。ありがとん
ファイル入出力に関する疑問 ファイルを効率的に配列に読み込むにはどうしたらいいか、という問題です。 普段は下記のようにfstreamを使って領域確保後に一気に読み込んでいました。(エラー処理等省いています) ifstream in( filename ); in.seekg( 0, ifstream::end ); *size = static_cast< int >( in.tellg() ); in.seekg( 0, ifstream::beg ); *buffer = new char[ *size ]; in.read( *buffer, *size ); しかし今回、上の意向でfstreamが使えなくなったので、stdioで同じように読み込もうと思ったのですが File* fp = fopen(filename, "rb"); fseek(fp, 0, SEEK_END); size_ = ftell(fp); data = new char[size_]; fseek(fp, 0, SEEK_SET); 配列を確保した後、まとめてデータを読む方法がわかりません。 getcで1文字ずつ読むと非効率的のような気がするのですが、そんなことはないのでしょうか?
fread
ブラック企業だお(^ω^)
freadなんてそのまんまな関数があるなんてしりませんでした、恥ずかしい・・・
631 :
デフォルトの名無しさん :2009/07/08(水) 19:38:05
例外の伝播経路情報を残しつつ、ログとかダイアログを出す等の 最終的な処理はできるだけ後方でやるためのコードを書いてみた のですが、いかがでしょうか。アドバイスお願いします。 #include <iostream> #include <stdexcept> class TestException : public std::exception { public: TestException(const char *p) : std::exception(p), m_pE(NULL) {} virtual ~TestException() { delete m_pE; } void chain(TestException *p) { if (m_pE != NULL) m_pE->chain(p); else m_pE = p; } TestException *m_pE; }; void a() { throw TestException("exception from a"); } void b() { try { a(); } catch (TestException &e) { try { e.chain(new TestException("exception from b")); } catch (...) {} throw; } } int main() { try { b(); } catch (TestException &e) { for (TestException *pE = &e; pE != NULL; pE = pE->m_pE) std::cerr << pE->what() << std::endl; } return 0; }
#include "main.h" //////////////////////////////////////////////////////////////////////////////////////////////// BOOL InitApp( int iCmdShow ) { WNDCLASSEX wcl; //HACCEL hAccel; wcl.cbSize = sizeof(wcl); wcl.hInstance = hInstApp; wcl.lpszClassName = APP_CLASS; wcl.lpfnWndProc = WindowProc; このようにインデントができるようになったらなw
633 :
デフォルトの名無しさん :2009/07/08(水) 23:02:59
たすけてーーー。 今回、初めてC++Builder5を使用してプログラムを作成していますが 何もわからない。 誰も頼る人がいないので初投稿です。 1、以下のようなテキストファイルが存在する。 --------------------------------- 1の要求を受付ました。 1の要求の応答を送信しました。 2の要求を受け付けました。 2の要求の応答を送信しました。 <-どんどん新しいデータが入る。 --------------------------------- 2、テキストファイルのデータを新しいもの順に表示する。 ※↓textArea?? --------------------------------- ↑新 2の要求の応答を送信しました。 <-新しいデータが来るたび一番上に追加される。 2の要求を受け付けました。 1の要求の応答を送信しました。 1の要求を受付ました。 --------------------------------- ↓古 上記のようなものを実現したいのですが、さっぱりわかりません。 誰か教えてください・・・(;;)w
1行ごとに全部リストとかに読み込んで逆順に出力すればいいよ
>>632 コピペすると大変面倒です。
インデント無しコードをコピペして再インデント、もしくは
>>631 のインデントが有効となる状態でコピペをする方がいい。
というか、再インデントが一番楽。
638 :
デフォルトの名無しさん :2009/07/09(木) 07:27:26
C言語の定番的な初級本・中級本を教えて下さい。 作りたいものはデータ入力したものをソートしディスプレイ表示と印刷するものです。エクセルで出来るのですが定型的なものを作りたいのです。 経験はN88BASICコンパイラ(20年前)です。 独習します。周囲には詳しい人がいません。よろしくお願いいたします。
640 :
デフォルトの名無しさん :2009/07/09(木) 07:41:59
>>639 うわ!
どうもありがとうございます♪
早速しらべます!
641 :
デフォルトの名無しさん :2009/07/09(木) 09:03:35
VC2008 MFC SDIでの質問です。 xxxView.cpp でファイルオープンしてパスを Cstring filename に格納し、 xxxDialog.cpp で利用するにはどうしたら良いですか? 宜しくお願いします。
>>641 Mediatorパターンつうのか、
どちらのウィンドウクラスからもアクセス可能な第3者のクラスにファイル名を管理させれば?
第3者ってのは、たとえばメインウィンドウクラスとか、アプリケーションクラス
643 :
デフォルトの名無しさん :2009/07/09(木) 12:45:52
>>641 ありがとうございます!
気付きませんでした!
こうしてデザパタ信者がまたひとり誕生するのであった
645 :
デフォルトの名無しさん :2009/07/09(木) 13:11:27
642です。 Mediatorパターン以外にもやり方はありますか?
問題の要点はこういうことだな 「お互いにアクセス手段を持たない2つのオブジェクトが情報をやりとりするには?」 ↓ここで識者登場
>>641 ダイアログクラスのインスタンスにパスを設定してからダイアログ開く
648 :
デフォルトの名無しさん :2009/07/09(木) 14:00:28
cinで入力を求めるとき一定時間入力がなかったらデフォルトコンストラクタを返すにはどうしたらいい
デフォルトコンストラクタを返すってどういうこと
>>638 さりげなく N88BASIC でなく、N88BASICコンパイラ って辺りに渋みを感じた
>>648 タイマー付きのistreamっぽいクラスを作ってcinの代わりに使う
652 :
デフォルトの名無しさん :2009/07/10(金) 12:48:14
>>647 ダイアログクラスのインスタンスにパスを設定してからダイアログ開く
がぐぐってもの良く解りません。
誰か詳しく教えてください。
C初心者です。ちょっと質問させて下さい。 main() { int i = 6, j = 4, k; k = ++i * --j; k = i++ + k / j--; k = i * j - k; printf("%d", k); } という問題で苦戦してます。 優先順位や結合規則がイマイチわかりません。 答えは2になるみたいですが、どういった流れでトレースしていけば良いのでしょうか?
>>654 優先順位の高い物からカッコでくくれ
k = (++i) * (--j);
k = (i++) + (k / j--);
k = (i * j) - k;
優先順位で特に覚えておかなくちゃいけないのは2種類 1、関数の()、配列の[]、マンバ呼び出しの.と->は最上級 2、タンコ演算子(&、*、+、−、++、−−など)は第2位で、結合方向が右から左。 3、参考演算子と代入演算子も結合方向が右から左。 これだけしってればあとは祝詞勢い。
>>655 >>656 レス有難う御座います。助かります。
明日、C言語検定3級の試験がありまして、その試験勉強をしているところなのですが
分からなくなったらまた質問してもよろしいですか?
5時間以上考えるか調べるかしてそれでもわからないなら質問していいよ
>*<
>>654 の件なのですがすいません。えーと・・・
自分なりにトレースしながら計算してみたんですが
一行目でi=7、j=3、k=21
二行目でi=8、j=2、k=18
三行目でk=-2
という様に代入されていって答えは-2になってしまったのですが
解答を見ると2になっています。どこが間違っているんでしょう?
二行目、後置演算子。
>654みたいな問題の存在意義が解らない。 こんな糞コードが世に放たれることがないよう 最初から可読性を重視したコーディングを 覚えさせる方が先じゃないのかね?
^>^
連投すいません。 main() { int l = 7, m = 6, n; n = l >= m; n += l == m + n; n += l != m + n; printf("%d\n", n); } 関係演算子や等価演算子は、繰り返し文でしか使ったことが無かったものですから 一体何の値がnに代入されるのか見当もつきません。ご教授お願いします。
C言語の場合、比較演算子、関係演算子、論理演算子の結果は 真ならば1、偽ならば0と定められてる。 余談だけど○○==TRUEってコード書くと 死ぬ目に遭う事になるかもしれないよ
五時間考えろと言われなかったか? 優先順位を元に括弧で囲めというアドバイスはもらわなかったか? なぜ何もしない状態で出てきた?
○○==trueならそうそう死にはしないだろうけど、TRUEはだめだな。
>>669 できました!助かります。
>>663 C担当の講師も同じようなことを言ってました。
彼曰く、C検定の勉強は不細工なソースでも読めるようになるための
勉強であって、実用的ではないのでプログラムを組む時は真似しないように。
とのことでした。
>>669 すいません。
独学でこつこつやっていて、セミナーには週に一回しか通っていないので・・すいません^^;
あれ、俺独学でこつこつやってる人のイメージ間違えてたかも
正直もっと前から始めるべきでしたw こんなんじゃ間に合わねーって焦り出して一昨日から徹夜してました。 皆さんのお陰でなんとか受かりそうです。本当に有難う御座いました。 もう真夜中ですがまた何かありましたら宜しくお願いします<( _ _ )>
ClassA A, B; A = B; となったとき、最初の宣言時のAはどこへ行っちゃうんですか?
Aに割り当てられたメモリに、Bの内容がコピーされる。 だから、どこかへ行くのではなく、自身の形がBと同じ内容に書き換わる、が正解。 具体的に内容がどうコピーされるかは、operator=()次第だけれども。
>>678 知識確認。
変数とかメモリって知ってる?
ClassA A; // メモリ領域にAの内容が展開(インスタンス化)され、変数Aはその参照のような状態になっている
ClassA B; // もう一個生成する
A = B; // 参照だけ置き換えてしまった事で、元々のAの領域はリークのような状態になってしまう
・・・みたいな想像したのではないかとエスパー。 しかし正解は
>>679
>>681 みたいなことをやりたいなら
独立参照が必要ですなぁ。
>>678 まずはC言語を学ぶといいよ。
いろいろ躓きづらくなる。
=を定義してないとビットレベルで上書きされる
そうでもない
全ビットコピーは組み込み型だけ。 ユーザー定義型は代入演算子の挙動次第。
HWPS! ≫ #pragma once
ttp://holy.enyou.org/2007/09/09/pragma_once/ ここの
> しかしこのアプローチは、2つの異なる場所に書かれた
> #include 指示子が同じヘッダファイルを指しているか
> どうかを知るのが根本的に困難であるため、
> うまくいかないことがある
> (例えば、シンボリックリンクの場合)。
この意味が分かりません。
どういう状況のことを言っているのでしょうか?
>>686 例えばfoo.hがある場合、ln -s foo.h fooz.hとして
#include "foo.h"
#include "fooz.h"
としたときにpragma onceでインクルードガードをするのは難しいと言うこと。
>>683-685 > =を定義してないとビットレベルで上書きされる
> 全ビットコピーは組み込み型だけ。
> ユーザー定義型は代入演算子の挙動次第。
class MyClass
{public :
unsigned int num;
double x;
YourClass hoge;
};
というクラスがあったとすると、
「コンパイラが自動生成する」MyClassのoperator=(const MyClass&)の定義は
YourClassのoperator=(const YourClass&)の実装次第って事かい?
>>687 確かに普通のインクルードガードなら
そういったシチュエーションでも
対応できますね。
ありがとうございます。
質問です。 次のような時、関数内で配列数を取得する方法はありますでしょうか。 void func(const char* p) [ // ここで配列のサイズを知りたい // しかしこのポインタが、実は関数の外で配列のアドレスがコピーされた物だ、 // という事を知るすべが無いから、知りようが無いような気がしています。 // 何か方法は無いでしょうか。 } void main() { char abc[100]; char *p = abc; func(p); }
不可能 サイズも一緒に渡すかコンテナを使う
template <int N> void func(const char (&a)[N]) { // Nは配列数 } という風にC++なら出来るんだがな
無い。 呼び出しにsize_tを追加するか、構造体を渡すのが定石。
>>690 そのサンプルのような使い方を想定する場合、ナル文字を探すと言うアプローチで充分。
何故なら、const char *である以上格納は行なえないから。
>>694 Boostのソース見てみろよ
もっと凄い事いっぱいしてるから
>>692 これ見るたび感心するんだけど、いざ使いたいときには思い出せないんだよな・・
>>694 こんなのを作るのは、C++使いの誰もが通る道。
template<typename T, std::size_t N> inline std::size_t numberof(T (&)[N]) {return N;}
>>692 のやり方でも
>>690 みたいに一度ポインタに渡してしまうと
配列数の情報が失われてしまいコンパイルエラーになる
あくまでも func(abc); のように呼び出す事が原則
700 :
694 :2009/07/11(土) 23:12:45
>>698 > template<typename T, std::size_t N> inline std::size_t numberof(T (&)[N]) {return N;}
ええと、これはつまり
任意の型の配列を受け取れて、
TやNはコンパイラに推論させることで
こちらが打ち込む必要はないって事ね。
どうも。
>>692 これ2次元でも大丈夫なのね
Sugeeeeee!
2次元配列の受け渡し問題がついに解決したわ
702 :
690 :2009/07/11(土) 23:29:58
ありがとうございます。やっぱり無理か・・ 素直にエイリアス受け取るか、\0探す形にします。 あと、 templete 微妙に書かれてる内容の意味がわからないので (特に N をどうやって取得するのか) これから勉強します
703 :
690 :2009/07/11(土) 23:33:25
ちなみに、
>>698 のテンプレートって、要は
char abc[100];
int l = sizeof(abc)/sizeof(char);
の、任意型バージョンみたいな動作って事になるんですよね?
>>697 使うだけなら<boost/range/size.hpp>のboost::sizeを使えばいい。
もっとも、Boost.Rangeの一部なんで、STLコンテナやBoost.Arrayなどにも返事を返すけど。
705 :
678 :2009/07/11(土) 23:42:24
情報不足で色々エスパーしてもらって申し訳ないです。 ClassA はそのなかでオブジェクトを生成したりしてるので、 どうなっちゃうんだろうと思ったのです。 何も考えずともC++がAを削除してからBをコピーしてくれるのか クラスを書く人がoperator=()を上書きしてあげないといけないのか。 679さんの説明だと、ほんと=次第というか、class書く人間が 考慮してあげないといけないようですね。 うう・・・めんどくさい。 代入されたときの挙動まで考えるぐらいなら、 いっそ=を禁止したい(コンパイルレベルで
>>705 >C++がAを削除してから
この表現がまた怪しいな。
>ClassA はそのなかでオブジェクトを生成したりしてるので、
pimplイディオムを使ったことある?
浅いコピーとかディープなコピーとか聞いたことある?
private: type& operator=(const type&);
>>705 取り敢えず、EffectiveC++くらいは読んでからクラスの設計をするといいと思うよ。
>>703 テンプレート版のいいところは、配列以外だときちんとエラーになること。
char * pに対してsizeof(p) / sizeof(* p)なんてしたらどうなるかと思うとw
但し、>698のように小さい関数として実装する分には最適化で消えてなくなるからいいけれど、
>692のように大きい関数で使うとサイズの違う配列を使うたびに実体が作られることに注意。
関テのテンパラはパラからコンパが類推するから、 配列aに対して単純に numberof( a ) のように記述すれば、aの要素数が返る。 どこでも使える。 問題は、この関数は要素数の異なる配列ごとに 別々のコードが生成されるのでコードが肥大化するって言う点。 どう見てもnumberofはコンパイル後に定数に置き換わるようなないようだけど 現行のコンパイラはまだそこまで賢くない。 テンプレートメタプログラミングがもっと一般化すれば これはとても良い具合になるはず。
>>709 最近のコンパイラを舐めない方がいい。つーか、調べずに書きなさんな。
iccは勿論gccでも>698は最適化で定数に成り下がるよ。
>>709 の知識はそこまで最新じゃないんだろ。
コンパイラ作っている人ってホント尊敬するわ。
ち。
普通にvectorとか使った方が速いようなw
動的配列で使えたら最高なのに
>>713 何とvectorを較べてるの? まさかとは思うけど、vector::size()が速いなんて思ってないよね?
>>714 動的配列が欲しいなら、それこそvectorの出番。
>>715 スピードが、じゃなくて、手っ取り早いって意味ね。w
>>690 の用途ならvectorで十分じゃない?ってこと。
リニアなスピードが要求されるならともかく。
ここでvectorじゃなくてstringだろ、という揚げ足取り↓
揚げ足じゃなくて至極もっともなツッコミだったな
多次元配列の要素数を知りたいときはどうしたらいいのだ。 つまり、次元数も込みで、という意味だよ。^−^
それが可能なコンテナを使う、かなあ
>>708 <windows.h>のARRAYSIZEマクロを見るがいい。
テンプレートを使いつつ、sizeofによって確実にコンパイル時定数にしている。
まあ最適化目的よりも、言語仕様で定数が要求される場所でも使えるという意味合いのほうが大きいだろうけど。
> extern "C++" // templates cannot be declared to have 'C' linkage
> template <typename T, size_t N>
> char (*RtlpNumberOf( UNALIGNED T (&)[N] ))[N];
>
> #define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A)))
> #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)
すみません、質問です。 Win32環境で、メモリに既に読み込まれているバイトデータ(char*)に対して、 FILEハンドルを与える方法って無いでしょうか。 // 普通にファイルのハンドル FILE *fp1 = fopen("C:\\hoge.txt", "rb"); FILE *fp2 = メモリに既に読み込まれているバイトデータに対してファイルコンパチなハンドルを生成 やりたい事は、ファイルストリームと互換性のあるメモリストリーム実装です
>>724 メモリ空間をドライブとしてアクセスするためのドライバ(所謂RAMDRIVE)を作ればFILEをどうこうする必要はないよ。
そうでないのなら、いくらFILEと互換性を持たせてもライブラリ関数(例えばfputc)も自前で実装しなおす必要が出てきてしまう。
>>725 すみません、やりたい事について情報が曖昧でした。
既存のライブラリの関数(具体的には lpng の関数 png_init_io(png構造体ポインタ、FILE*) )に、
既にPNGファイルイメージが生成してあるメモリ領域の char* を渡して、最終的に HBITMAP ハンドルを受け取りたいんです。
[PNGのメモリイメージ] → (変換) → [HBITMAP としてハンドル取得]
^^^^^^ この部分を lpngライブラリに任せている。その際、FILE* が必要
生き物の祖先は魚(みたいな何か)のはずなのに なんで虫にはあばら骨がないの?
1.宇宙から来た(別の進化の系統に属する)から 2.実は魚に背骨が出来たのはずっとあと(マジで) 1または2、どちらか好きなほうを採用してください。
731 :
726 :2009/07/12(日) 16:15:22
>>728 すみませんでした・・ いきなり解決しました。 ただのコールバックだったのかorz
もしかしてコンパチFILE*を簡単に生成する方法でもあるなら、他の用途でも使えるかなとおもって
最初のような書き出しになりましたが、目的はこれで達成できます。 ありがとうございました。
目的明かしてスレチ確定。orz
>>727 そこまでの実装は望んでいなかったので、すみません
>>728 その程度のことで画像処理のスレに誘導しないでください。あっちでライブラリの使い方を聞いても答えられませんし。
>>726 Cygwinだとfmemopenが使える。
VCなら、_pipeでパイプを作成して、それを_fdopenでFILE*にするのがいいと思う。
_pipeは読み取り用と書き込み用の2つのファイル記述子がもらえるので、
書き込みのほうへ自分のデータを書いて、読み取りのほうをpng_init_ioに渡す。
734 :
733 :2009/07/12(日) 16:46:02
あれ、もう解決してた?すまん。
aaa.cpp(main関数を含む。foo.hをインクルードしている。) foo.h(class fooの宣言と定義を含む。) foo.cpp(class fooの実装を含む。) この時、g++ aaa.cppだけではコンパイルは出来ますがリンカエラーになります。 g++ aaa.cpp foo.cppとすれば実行ファイルまで出来るのですが、 これを他人に言いたい時はなんというのでしょうか? foo.cppをリンクしてくださいで用語として通用しますか?
分割コンパイルのやり方を調べれ
g++ aaa.cpp foo.cppしてください この辺りは方言多いので省略すると通じない可能性高いし、 そもそもcppファイルはリンクするものじゃないし
fooがライブラリとして foo.h foo.cpp の形で公開されていて、 この使い方を問うときに 適当な日本語が欲しいのです。 foo.hをインクルードしてください だけでは動きませんよね? 皆さんはこの場合どうやって伝えていらっしゃいますか?
libfooをリンクしろ。ヘッダはfoo.h。 これだけで伝わるだろ。
>>738 foo.hとfoo.cppが与えられたら、使い方なんて一通りしかないんだから、何も言わなくてもわかる。
> fooがライブラリとして > foo.h > foo.cpp > の形で公開されていて、 「ヘッダをインクルードして下さい。プロジェクトに foo.cpp も追加して下さい」
743 :
740 :2009/07/12(日) 23:05:52
コンパイルとかリンクの話はオライリーのC++クックブックがわかりやすかった
740 名前:デフォルトの名無しさん[sage] 投稿日:2009/07/12(日) 22:43:41
>>738 foo.hとfoo.cppが与えられたら、使い方なんて一通りしかないんだから、何も言わなくてもわかる。
741 名前:デフォルトの名無しさん[sage] 投稿日:2009/07/12(日) 22:49:41
> fooがライブラリとして
> foo.h
> foo.cpp
> の形で公開されていて、
「ヘッダをインクルードして下さい。プロジェクトに foo.cpp も追加して下さい」
742 名前:デフォルトの名無しさん[sage] 投稿日:2009/07/12(日) 22:55:50
>>741 プロジェクトってなんですか?
743 名前:740[sage] 投稿日:2009/07/12(日) 23:05:52
>>741 ありがとうございます。
それで行かせていただきます。
>>742 失せろヴォケ
740=743???
関数ポインタと関数参照ってどう違うの?
関数ポインタ = 関数を指しているポインタ → 指しているのは関数だが、ポインタなので計算出来る 関数参照 = 関数のアドレス。元の関数のエイリアス → 指しているのは関数だが、ポインタじゃないので計算は出来ない
>>747 に続けて使用例から見た違い
関数ポインタ ・・・
ポインタなので、関数を列挙した配列(関数テーブル)を順に移動しつつ処理するみたいな事が出来る
関数参照 ・・・
ただのエイリアスなので、元の関数を呼ぶだけ = その関数にだけ用があるようなコールバック動作の為に良く使う
thx ポインタ⊃参照な感じか
Haagen-Dazs
はあ?って書こうと思ったら、間違えて変換してしまった。すみません。
ファイルから読み込んだデータは、C++の場合どのように持つのが定石なのでしょうか? 読み込んですぐ捨てるようなデータではなく、プロセスが生きている間使うようなデータです。 Cの場合だとグローバル変数として宣言した変数に入れると思うのですが。
Cでもまともなプログラムならグローバル変数になんか入れねえよ
いれるだろ? まさか共有メモリを確保して・・・とかいいだすんじゃないだるな?
入れねえよ ・・・ 「配列確保して持っとくみたいな事しねぇよ」 入れるだろ ・・・ 「malloc した後のポインタやサイズを持っとくだろ」 こんなすれ違い
C++でC言語のsscanfと同じような働きをするクラスか関数は どんなもんなんですか?
遅くてもいいから、どうしても C++ のストリームを使いたい、ってことなら strstream から >> 演算子で入力。 まあふつーは std::sscanf。
遅くてもって どんだけ大量のストリーム流し込む気だよ
std::strstreamなんて使うなよ 前のC++の遺物だぞ 今はstd::stringstream、std::istringstream
ここで敢えてregexを持ち出そうではないか。 本当はxpressiveを使いたいところだけど。
ストリームをメモリにぶっこむのになぜ正規表現
最近覚えたとかか
>>761 区切り文字とかの規則がある中から文字列を切り出すようなことだろうと感じたから、
それには正規表現も選択肢の1つとして不思議ではないと思った。
マルチスレッドの質問です。 インテルCPU, WindowsXP、Win32の処理系において下記のようなモデルを考えた時、 マルチスレッド間で1の処理や4の処理を if(式) として記述した時、その式評価中に割り込まれるような事は あるんでしょうか。 TLS でない volatile なグローバル int A (実際には構造体のメンバ) 主スレッド 1.A の 第2ビットが 1の時処理をスキップし、0の時、第1ビットを立てる 2.〜スレッド間共有構造体にアクセス〜 3.第1ビットを降ろす 副スレッド 4.A の 第1ビットが 1の時処理をスキップし、0の時、第2ビットを立てる 5.〜スレッド間共有構造体にアクセス〜 6.第2ビットを降ろす 要はOSのスレッド処理の分解能の単位が知りたいのです。
割り込まれます。 条件式をチェックしている間に、 別のプロセスに値を書き換えられたりとか普通。 だから条件式全体をむーてくすとかせまふ男とかで囲ってロックしないと 大変なことに。
InterlockedCompareExchange使えって課題か? それはともかく、volatileがマルチスレッドに効果あると謳ってるのはVC独自だよ。 gccなんかはそういう保証は付けていないはず。
768 :
764 :2009/07/13(月) 23:34:01
やっぱり割り込まれるか・・・ ちなみに、
>>764 の1の処理、仮にフラグを1つだけにして、
そのビットが立っていれば主スレッドが構造体を触る権利を得て、降りていれば副スレッドが権利を得る
というルールにした場合に、評価式を
主
if(A^=1) {
構造体を触る
}
副
if(A^=1) {
} else {
構造体を触る
}
のようにしていたとしても、代入と評価の2ステップの間に割り込まれてしまうって事ですよね?
>>767 いえ学生では無いので課題とかではありません。
ちなみに volatile の動作って最適化を抑制してレジスタでの持ちまわしを止めさせる
= 常にメモリへのread/writeを行う事で整合が取れない自体になるのを抑える、みたいな感じでしたっけ。 VCの場合
769 :
764 :2009/07/13(月) 23:37:19
・・・すみません。てか毎回代入したら意味無い やっぱダメだorz
>>767 volatile は、最適化されてメモリ上にとられなくなってしまう、という事態をなくすのではなかったかと。
とすれば 必要条件であっても十分条件ではないのは vc でも gcc でも同じはずでは
主 if(A&1) { 構造体を触る A^=1; } 副 if(A&1) { } else { 構造体を触る A^=1; }
ちゃんと道具があるのにそれを使わずにどうにかしようっていうのはおかしいよね 包丁使いたくないからカッターでどうにかする的な。
ああでもどっちかがやったならもう片方はスルーすんのか
揮発変数の読み書きを最適化によって消してはならないのと命令の順序を入れ替えてはいけないのは規格で決まってる。 もっともCの規格にスレッドに関する規定が何もないので、それがマルチスレッドにおいてどう働くかは定められていないが。
だって volatile って元々、メモリマップドI/O 用でしょ? 同じ値を何度も書き込むことに意味があったり 同じ変数を読むたびに違う値が取れたり。
そそ、マルチCPU環境でCPU1からの書き込みがCPU2からの読み込みの前に行われる保証なんて誰もしてくれない。
>>771 だからそれだとifの評価の後Aが変えられてるかもしれないので
意味がないって話じゃないか?
評価→処理→フラグ更新
‥例えば主側のこの流れの間に副側がズレて重なってる可能性があるから
ダメって事
C++のstringstreamで data%d.dat という文字列があったときに data1.dat data2.dat ... という文字列にして出したい場合はどのようにすればよいのでしょうか?
基底クラスAの派生クラスBと同じく基底クラスAの派生クラスCがあって、 クラスBのメンバ関数で基底クラスAのメンバ変数の値を変更したとき この値をつかって派生クラスCのメンバ関数で基底クラスAのメンバ変数について何らかの処理をさせたい場合はどのようにすればいいのか 簡単な例でいいので教えていただけませぬでしょうか?
>>781 それ要はクラスBとCって異なる二つのクラスのインスタンス同士で、
たまたま同じ基底であるA側のレイヤにあるメンバを触りたいって話か
>>781 >基底クラスAの派生クラスBと同じく基底クラスAの派生クラスCがあって、
クラスA─(派生)→クラスB
クラスA─(派生)→クラスC
クラスB b;
クラスC c;
>クラスBのメンバ関数で基底クラスAのメンバ変数の値を変更したとき
b.proc(10); // メンバに10を格納
>この値をつかって派生クラスCのメンバ関数で基底クラスAのメンバ変数について
>何らかの処理をさせたい場合はどのようにすればいいのか
c.proc(ここにインスタンスbが保持する値を渡したい?);
継承元が異なってたとしても、単にインスタンスbに、cを渡してなんか処理すりゃいいんじゃね?
文面からまるで、b と c が aでつながってるとでも思ってるかのように見えるんだが
hello.exeつくろうとしたらこうなたました C:\aa>bcc32 hello.cpp Borland C++ 5.5.1 for Win32 Copyright ( hello.cpp: Error E2209 hello.cpp 2: Unable to open Error E2282 hello.cpp 3: Namespace name Error E2451 hello.cpp 7: Undefined symb Error E2451 hello.cpp 7: Undefined symb *** 4 errors in Compile ***
報告ご苦労。下がってよいぞ
>>788 > 答えないならやめて
おいどんだけ偉そうなんだよ。
> 移しただけ
そんな言い訳が有効だとでも?
それなら全てのマルチポストが許されるだろうが。
頭おかしいの?
>>789 いや、お前の回答が無意味じゃん。聞く場所こっちのほうがいいかなっておもっただけ。
>おいどんだけ偉そうなんだよ。
マルチポスト乙。
消えろヴォケ。
おつかれさまです><
>>790 は?
お前マルチポストってなんだか分かってる?
重症患者?
そんな**にはプログラミングは不可能ですよ、無能君www
>>792 マルチ廚マジキモい、IDあったらいいのに。うんそうだね。マルチあるといけないからそうやってキモウザイ事ばっかやってれば役立つかもね
>>793 必死だなw
> hello.exeつくろうとしたらこうなたました
とか言ってるお前の脳がどうかしているとしか思えない。
・・・ま、いいよ。
何を2chでほざこうと、
お前が自身のプログラミングの無能さのせいで
現実で無職になれば、俺はそれで満足だから。
俺の出番だな。
>>785 別のスレに回答しておいた。
関数内でインスタンス生成したものって関数が終了したら消えますか? それとも、deleteで関数終了時に消去するようにしなければならないでしょうか?
自動変数として生成したものは消えます newで生成したものはdeleteしなければなりません
auto変数がデストラクトされる仕組みって、 最初はよくわからなかったけど(俺だけか?) アセンブリ吐かせて中を見ると、関数の最後で律義にデストラクトしまくってるんだよね 初心者はぜひやってみて
一応補足。当たり前だけど、中に別のインスタンスのポインタを持つ自動変数の場合、 中ポインタ変数については一緒に廃棄されるけど、ポインタの指す先は勝手に解放なんて されないので初心者は注意すること
ありがとう御座います、関数を生成するたびに引数にあわせて生成するインスタンスが変わるので 解放されないと大変な事になる気がしたので質問しました。助かりました、ありがとう御座います。
C++を使い始めた最初は、やっぱみんな自動変数の破棄が心配でこういうの書いてみるよな #include <cstdio> int count = 0; class hoge { public: int id; hoge() { id = ++count; printf("construct <%d>\n", id); } ~hoge() { printf("destruct <%d>\n", id); } }; void main() { hoge obj; // objは自動的に破棄される hoge array[2]; // array[]の要素はすべて自動的に破棄される hoge *p = new hoge; hoge *q = new hoge[2]; delete p; // これを書かないとpが指すインスタンスは破棄されない delete[] q; // これを書かないとqが指すインスタンス配列は破棄されない }
class A { }; A* p = new A[10]; delete[] p; // ←ここ!! 「ここ!!」で10個のインスタンスが破棄されるってことは、 pが10個の要素を持つことをコンパイラは知ってるんですよね? この個数をプログラマが参照できれば配列引数とかの受け渡しに便利なのに…
すべての実装が必ずしも大きさを覚えているとは限らない.
operator new を自作すればそんなことも可能になるよ。
配列の途中から渡された場合に困ると思う
>>803-805 どもども。そりゃそうですよね…
operator newまわりは、まだ俺にはアンタッチャブルな気がするので
もうすこし勉強してみます
807 :
デフォルトの名無しさん :2009/07/15(水) 19:58:48
でも
>>802 を見て、「あぁ、じゃあ元が配列なポインタなら全部 delete [] で開放出来るんだ」 とか
単純に理解してしまうと、次のようなケースでハマるかもしれない。
A* p = new A[10];
delete[] p; // これはOK
A a[10];
A* p = a;
delete [] p; // コンパイルは通るが実行時エラー(於いてVC)
前者は 「自動変数でない配列を動的に生成した。その際のポインタなので delete[] で開放出来る/しなければならない」
後者は 「スコープ外れると開放される自動変数のアドレスをコピーしたポインタ。指す先は必ず開放されるので、それより先に開放してはならない」
ちょっと考えればすぐ気づくと思うけど、初心者が誤解して覚えてしまうとアレなので補足
808 :
デフォルトの名無しさん :2009/07/15(水) 20:20:16
質問なのですが、 fprintf(fp,"%lf\n",(double)((short)x)); という文は何を示しているのですか? fpで開けたファイルにxという数字をdouble型で格納しているのでしょうか? shortとは何を示しているのでしょうか?
自動変数ってスタックにとられるのではなかったか?これはC だけの話?実装依存の話?
>>810 実装依存。スタックだのヒープだのの概念が無い計算機上でもC/C++の実装は作れる
>>808 見たまま、shortのビット幅に一旦収めた(端数を捨てて整数化した)あと、
doubleの幅に拡張してから表示させようとしてるんじゃない?
それ自体何故そんな事してるのかってのは、書いた人の都合だろうとしか言えないが
813 :
デフォルトの名無しさん :2009/07/15(水) 20:52:57
最適化について聞きたいんだけど、 for ( int i = 0; i < 10000; i++ ) { pObj->pTable[ i ] = i; } と char* pTable = pObj->pTable; for ( int i = 0; i < 10000; i++ ) { pTable[ i ] = i; } gcc4.0で、速度優先で最適化を掛けた場合、どっちが早いでしょうか。
>>813 その程度で差が出るようなコンパイラは馬鹿です。
>>808 そのコードがレガシーC或いはC89などのC99以前のCであるならば、フォーマット文字列が規約違反です。
>>813 pObjがグローバル変数だとしたら、前者と後者では意味が変わるのだけど。
817 :
デフォルトの名無しさん :2009/07/16(木) 00:16:43
テキストデータをバイナリデータとして保存しようとし、下のプログラムを作りましたが動作しません。
何が悪いのですか?windowsのcygwin環境のC言語です。
書き込めなかったので次のレスにまたがって書きます。
#include<stdio.h>
#include<string.h>
#include<math.h>
int main(int argc, char *argv[])
{
char c;
int i,j,count;
FILE *fp,*fp2;
if(argc!=3){
printf("Usage is ...\n");
printf("trans.exe <input file> <output file>\n");
return(-1);
}
/* ファイルオープン */
if((fp=fopen(argv[1],"r")) == NULL){
return(-1);
}
if((fp2=fopen(argv[2],"wb")) == NULL){
return(-1);
}
>>818 に続く
818 :
デフォルトの名無しさん :2009/07/16(木) 00:18:52
>>817 から
/* テキストデータをバイナリデータに変換/書出し */
while(1){
fgets(&c,1,fp);
if(feof(fp)){
break;
}
fwrite(&c,sizeof(double),1,fp2);
}
fclose(fp);
fclose(fp2);
return(0);
}
sizeof(double)?
>char c; 〜略〜 >fwrite(&c,sizeof(double),1,fp2); これは一体
821 :
デフォルトの名無しさん :2009/07/16(木) 01:03:06
>>819 >>820 別のプラグラムでデータタイプがdouble型で入力というプログラムを貰ったのですが、そのときにバイナリファイルを入力しろと言われたので、
バイナリファイルdouble型で入力しようとしました。
この場合はcの宣言をcharではなくdoubleにすべきだったのでしょうか?
ファイル処理はCの絵本という本のみで学んだ(?)ので知識がほとんどありません。
元のテキストデータってのは何? ↓こんな感じで人間が読める形の実数がずらずら書かれてるってこと? 1.41421356 1.7320508 2.2360679 :
823 :
デフォルトの名無しさん :2009/07/16(木) 01:24:46
↑入力ミスってたので1行修正 fwrite(&data, sizeof(double), 1, fp2); fwrite()の第2引数と第3引数の順番て、いつも間違えるのさ・・・
826 :
デフォルトの名無しさん :2009/07/16(木) 02:26:41
>>824 >>825 d。だけどfgetsとfscanfは何が違うんでしょうか?
fgetsはテキストファイル読み込みと書いていたんですが。。
>>826 読み込んだものをどうするかが違う。
fgets()は文字列として読み込んだまま。
fscanf()はフォーマット指定に基づいて入力を分解し、型に合わせて変換してくれる。
828 :
デフォルトの名無しさん :2009/07/16(木) 03:05:04
>>827 なるほど、fscanf()は少し入力量が多いものの優秀(上位互換)ということか。
勉強になりました、ありがとう
829 :
悩み人 :2009/07/16(木) 06:32:30
C++での日数差を計算するプログラムが全くわかりません。 西暦と月と日にちを入力して計算します。 どうか教えていただけませんか? かなり悩んでます。早い解答待っています。 どうかお願いします。
つ[<ctime>]
struct tmに入れて、mktime()でtime_tに変換、difftime()で差の秒数にしたら、86400で割れば日数だね。
832 :
悩み人 :2009/07/16(木) 07:55:57
プログラミングが初心者でよくわからないのですが、頑張ってみます。 他に簡単な方法があれば教えて頂きたいのですが、ありませんか?お願いします
理屈上は、年月日をを通算日数に直して差を求めればいい たとえば2009年に限って考えると、2009/7/16は2009年の197日め、2009/12/31は365日目、 その日数差は168日になる。これはOK? 同じようなことを、たとえば「西暦1900年1月1日からの通算日数」でやれば 西暦1900年以降のどんな年月日についても日数差が計算できる。 で、その通算日数みたいなものを求めるには、ふつうはmktime()関数を使う。 これを利用しないで自分でがりがり計算するやつは、まずいない。
834 :
デフォルトの名無しさん :2009/07/16(木) 16:07:47
【緊急】 手元に参考書がない・・・ 誰かBCB5でのSetTimer,KillTimerの使い方おしえて SetTimer 引数 戻値 説明 KillTimer 引数 戻値 説明
人様の作ったソースを読んでいるんですが typedef struct table_a{ int s_line; int e_line; }TABLE_A int pp(TABLE_A table[], int x, char t);; というのはtabel_aというタグ名の構造体を定義して それをTABLE_Aという名前の構造体型として定義してるんですよね。 その後なんですが、int型のppという関数を作る所の TABLE_A table[]とは何でしょうか? 引数にTABLE_A型の…table[]とは?
引数に配列演算子がついた場合は、ポインタの意味。 つまり、 int pp(TABLE_A *table, int x, char t); ってこと。
int hoge[]の[]と同じ、配列。 ただし、そこは関数の仮引数なので、TABLE_A *tableと書いたのと同じこと。
ポインタ表記じゃなくて、わざわざtable[]と書くのは、 「配列を渡すぞゴルァ」というプログラマの意思表示みたいなもんだね
841 :
デフォルトの名無しさん :2009/07/16(木) 18:00:01
標準入出力でやりとりをするa.exeとb.exeがあって下のように起動します。 a.exe -run "b.exe -bar -baz" 無限ループに入ってしまうのでやりとりの内容を知りたいのですが下のshowpipeの様な形で使えるプログラムがあれば教えて下さい。 a.exe -run "showpipe b.exe -bar -baz" もっと適切なスレッドがあれば誘導していただけませんでしょうか
tee とか。 ってexeと書いてるからWinだったりする?
a.exeとb.exeは双方向でやりとりするのかな teeだと一方向しか横取りできなくない?
845 :
841 :2009/07/16(木) 18:14:29
>842 windowsです teeは聞いたことがありますが双方向のやりとりでも大丈夫なんでしょうか?
双方向か、、まあc.exe作った方がはやいかもw
a.exeが作れるなら、showpipe.exeを作るのもそんな難しくないはず。 ここは自作にちゃれんじだ。
848 :
781 :2009/07/16(木) 18:25:59
ポインタ使って基底クラスの値を操作するのってだめなんだろうか?
>>781 なんだかとってもクソ設計に見えるのは俺だけではないだろう。
850 :
841 :2009/07/16(木) 18:36:39
a.exeはソースが公開されていないプログラムなのです・・・
それは関係ないだろう
852 :
841 :2009/07/16(木) 18:52:51
>>851 自作にチャレンジしていますが
windowsAPIでのプロセス生成やファイルハンドルの扱いを全くやったことがないもので・・・
もしかして標準c/c++だけで何とかなりますか?
#include <iostream> using namespace std; class A { public: int get() { return a_; } protected: static int a_; }; int A::a_; struct B : public A { void set( int i ) { a_ = i; } }; struct c : public A { }; int main() { B b; c c; cout << "before : " << c.get() << endl; b.set( 10 ); cout << "after : " << c.get() << endl; }
>>836 > 文面からまるで、b と c が aでつながってるとでも思ってるかのように見えるんだが
インスタンスって理解出来てるか?
>>852 標準Cだけだと、、、popen 使えればいけると思うけど試してない
856 :
841 :2009/07/16(木) 19:23:27
C(UNIX)でTCP/IP関連のソースを組んでいるのですが、socket( ) を非ブロックにすることは出来ますか?
char str[500]; char *x; x = fgets(str,500,ファイルポインタ); となっていて何も繰り返し処理が無い時って xの中身[0]から[499]までは読み込んだファイルの1文字目から500文字目までがそれぞれ入るんですか? もし配列が400しか指定してなくてファイルの文字数が500だった場合はどうなりますか?
859 :
デフォルトの名無しさん :2009/07/16(木) 19:56:14
BCB5でSetTimerを使用してるんだが はまってしまった SetTimer(Handle, NULL, 3000, (TIMERPROC)TimerProc); で 『E2235:メンバー関数は呼び出すかそのアドレスをとらなければならない』 というエラーが発生する。 第4引数が悪そうなのだがどうすればいい?
>>858 xじゃなくて配列はstrでは?
xは何が入るんだっけ、fgetsの戻り値って何だ?
>>858 500文字よりも前に改行があったら、その改行までしか読み込まない
改行がなかったら、499文字まで読み込んで、500文字目に '\0' を入れる
配列のサイズより長い文字列を読み込んだら死ぬ
>>859 そのTimerProcというメンバ関数の宣言にstaticを付ける
>>859 そう言われるからには、TimerProcは非静的なメンバ関数なのだろう。
SetTimerに渡す関数は静的メンバ関数か非メンバ関数でないといけない。
引数のウィンドウハンドルから本来のオブジェクトを取得する
(Set/GetPropやSet/GetWindowLongPtrなど)などして、
改めて本来のメンバ関数を呼ぶという作りにするのがおそらく一般的。
timerID(第2引数)がUINT_PTRだから、それ経由でthis渡すのもありか。
>>861 バッファのポインタ。つまり
char* x;
x = str;
と同じ。ただし正常に終了しなかった場合NULLが返される
>>858 ただし改行までだった気がする。行末を見つけたら改行終端で終わる。
途中でEOFになると、NULL終端。 配列サイズをオーバした場合異常終了として戻り値がNULL。
おまえら大嘘書き連ねるなよ。 fgets()は改行を見つけたらそこまで読み込みナル終端。 改行が見つからずにファイル終端になればそこまで読み込みナル終端。 バッファサイズをオーバーしそうならバッファサイズ-1バイト読み込みナル終端。 いずれの場合も戻り値はバッファを返す。
>>866 char str[400]; // ←配列が400しか指定してなくて
char *x;
x = fgets(str,500,ファイルポインタ);
という顛末を予想してレスしたのかもしれない
だとしても、黙ってバッファオーバフローするので戻り値がNULLになることはない罠。
>>870 だから「上記以外の場合」 を補足してんだろ。
100点満点の答えを言ったつもりだから補足なんかされると悔しいんだよ。
自分語りはいいから
涙を拭けよw
>>857 出来た気がします。何でするかはわすれてました。
876 :
デフォルトの名無しさん :2009/07/17(金) 05:49:31
これも std::ostream& os = std::cerr; これも std::ostream& os = std::ofstream(file); OKなのに なんでこれが std::ostream& os = strlen(file) == 0 ? std::cerr : std::ofstream(file); だめなんですか? 1>c:\program files\microsoft visual studio 9.0\vc\include\ostream(584) : error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : private メンバ (クラス 'std::basic_ios<_Elem,_Traits>' で宣言されている) にアクセスできません。 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> c:\program files\microsoft visual studio 9.0\vc\include\ios(151) : 'std::basic_ios<_Elem,_Traits>::basic_ios' の宣言を確認してください。 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> コンパイラでのこの診断により関数 'std::basic_ostream<_Elem,_Traits>::basic_ostream(const std::basic_ostream<_Elem,_Traits> &)' が生成されました。 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ]
877 :
デフォルトの名無しさん :2009/07/17(金) 05:51:13
キャストしたらいけた・・・ std::ostream& os = strlen(file) == 0 ? (std::ostream&)std::cerr : (std::ostream&)std::ofstream(file) ;
c ? a : b はaとbの型が同じじゃないといけない
879 :
デフォルトの名無しさん :2009/07/17(金) 05:57:24
キャストしたけどg++には怒られる pipo.cpp:170: error: conversion to non-const reference type `struct std::ostream &' from rvalue of type `std::basic_ofstream<char, std::char_traits<char> >'
>>865 ということは
char型のstr[0]に一文字目の文字列が入り
xにはstr[0]のアドレス値が入るということですか?
>>880 いいえ、
char型のstr[0]に文字列の一文字目が入り
xにはstr[0]へのポインタ値が入るということです。
ポインタ値ってstr[0]のメモリアドレスじゃないの?
そうかもしれませんし、そうではないかもしれません。実装依存です。
ポインタ値は型情報つきのアドレス値。 ハードによってはアドレス値ですらない可能性も。
昨日
>>837 で構造体について聞いたんですが、その後またわからない部分が出てきてしまいました。
typedef struct table_a{
int s_line;
int e_line;
}TABLE_A
TABLE_A *table;
// TABLE_A型(構造体)のポインタ型の変数を宣言
のすぐ後に
int line =1;
table[1].s_line=line;
TABLE_A *table
という使われ方をしているのですが、
typedef struct table_a[?]とか
TABLE_A table[]
のような宣言が無いのになぜ後ろで構造体配列のような使われ方をしているんでしょうか。
>>885 単に簡単に書くためのお約束だから気にするな。
887 :
至急伝授求む! :2009/07/17(金) 11:41:53
「error LNK2019: 未解決の外部シンボル _main が関数 ___tmainCRTStartup で参照されました」 なんだが、アプリケーションの種類以外の解決方法ある?
>>885 table[1] は (*(table + 1)) のことです
読み替えてください
ポインタを通したアクセスをあたかも配列アクセスかのように書けるのは、C言語の仕様です
>>887 Windows アプリケーションを
コンソールアプリケーションとしてビルドしたら
まあそうなるでしょうな。
>アプリケーションの種類以外の解決方法
何がしたいの?
>>883-884 うーむ、難しくてピンと来ない…。
>>865 の説明
char* x;
x = str;
と同じこと、というのは
x = &strじゃないからアドレスが代入されてるわけじゃないってことですよね。
ではもし「あいうえお」という文字列のファイルを読み込んだら
str[0]に'あ'、str[4]に'お'が入り、xには何が入るのですか?
*X = '●'なんてやってもstr[0]の中身は変わらない?
x = &str; と x = &str[0]; は異なるが x = str; と x = &str[0]; は同じ なので *x = 〜; とやれば str[0] の中身が変わる (ただし1個のcharに全角文字は入らないよ)
>>888 つまり
TABLE_A *table;
int line =1;
(*(table + 1)).s_line=line;
ということですか。
tableはTABLE_A型のポインタ変数だけど*で通常変数モードに切り替わるんですよね。
tableという変数は1つしかないし配列ではないのに、+1というのはどう働くんでしょうか。
+1が+2や+3になった時、アクセス先はどこになるんでしょう。
>>892 例えば、
TABLE_A hoge[100];
table = &hoge[0];
などとしていて、*table の後ろにもいくつか (この場合99個) の TABLE_A が存在している場合、
*(table + 1) で *table の次の TABLE_A (つまり hoge[1]) を指すことができる
>>892 つーか、int ai[10]; int * pi = ai;と状況は同じだよ。少しは頭を使いなさいよ。
895 :
至急伝授求む! :2009/07/17(金) 12:45:56
>>893 この場合配列として宣言してなくても*(table + 1)とすると
table1個分先のアドレスに通常変数モードでtable[1]があるように振舞ってくれるんですか。
>>894 すみません、Cの知識一切ゼロで昨日から読み始めたので…。
*(table + 1) と int ai[10];int *pi = ai;が
どう関係あるのかよくわからないです。
>>896 んじゃまず、ポインタと配列について勉強してきてくれ。構造体についてはその後だ。
つーか、初心者スレに逝け。
>>885 はメモリフォルトじゃないのかい?
どこにもメモリを確保している式なり文なりがないように見えるけど。
>>896 K&R第二版でも読んだら?
たった200ページで説明終了なので、
三日もあれば読み終わるよ。
>>898 すぐ後と書きましたがメモリ確保のくだりは特に疑問なかったので省略しました。実際には
table = malloc(sizeof(TABLE_A));
と
while(〜〜〜){
table = realloc(table, (line + 1) * sizeof(TABLE_A));
があります。
>>900 誘導されます。
はじめて読むPentium マシン語入門編という本に出てきた C言語の文がよく分からないので質問します MOV EAX, [EBX+5] [EBX+5]は「EBX(の内容)+5」をオフセットアドレスとするメモリの内容を表しています。 これをC言語で書くと int Data = 100; int *pData = &Data; int Result; Result = *(int *)((char *)pData + 5); C言語ではint型ポインタに単に5を加えた場合、 5にint型のサイズ(4バイト)を掛けた値を加えるものとして扱われるからです。 こういう風に書かれているのですが 「5にint型のサイズ(4バイト)を掛けた値を加えるものとして扱われるからです。」 の意味が分からないです。 「Result = *(int *)((char *)pData + 5);で」 なんで(char *)が出てくるの分からないです。 C言語とかよくわからないのですが解説してほしいです。
おー、説明すると長いよ。そこは読み飛ばしていいと思うぞ。 何より、C言語でもそんな書き方しないし。w 要するに、C言語のポインタというのは、単にアドレス値を格納するだけでなく 値を格納するのに何バイトを消費するかという情報も持っている。 こういうのを「ポインタ値」と呼ぶんだが、それはさておいて、 int* p、つまりint*型のpはint値を格納してあるアドレス値と、 そこから何バイト分を取り出してint値とみなすかを示している。 int型は4バイトなので、つまり、*pのように書くと、 pの持つアドレス値から4バイト分を取り出して、その情報をint値とみなすということになる。 次。p+5と書くと、pのアドレス値にint5個分が消費するバイト数を加算せよ、 という意味になる。つまり4バイト*5個で20バイトを足すわけだな。 一方、char型は1要素を格納するのに1バイトしか使わない。 char* pがあるとして、p+5と書くと、pのアドレス値にchar5個分が消費するバイト数を加算するから、 結局、1バイト*5個で5バイト分増加する。 んで、「Result = *(int *)((char *)pData + 5);」。 まずint*型のpDataをchar*型に変換する。 こうすると、保持するアドレスは一緒だが、指し示す値はchar型に変更される。 char*型であるpDataに5を加えるのだから、そのアドレスはちょうど5バイト分進む。 しかし、だ。これをこのまま*pDataのようにすると、 そのアドレスから1バイト分を取り出してchar値とみなしてしまう。 ほしいのはint値だ。だからもう一度pDataをint*型に変換する。 これにより、元のpDataから5バイト分アドレスが進んだpDataを int*型として得ることが出来たことになる。 さぁ、あとは*をくっつけて(デリファレンスして) その中身をint値として取り出そうじゃないか。 ちなみに、上記の話はすべて実装依存。 C言語の規格にはポインタがアドレスを格納するなどという話は一切でてこない。 メモリをどう管理するかはコンピュータによって異なるからね…。
>>904 なげーよ。
>>903 Cは気にしないでいいよ。アセンブラはCより低レベルを扱うと言いたいだけだろうから。
ちなみにアセンブラでも、 MOV ECX, [EBX+EAX*4] みたいに4の倍数のオフセットが使えたりするでしょ。 あれも、こういったデータサイズの話に関係してるわけですよ
907 :
903 :2009/07/17(金) 17:14:42
>>904 非常に詳しい解説ありがとうございます。
C言語の本と併せて読んで理解したいと思います。
>>905 >>Cは気にしないでいいよ。アセンブラはCより低レベルを扱うと言いたいだけだろうから。
MOV EAX, [EBX+5]
これが
Result = *(int *)((char *)pData + 5);
になるのが全然理解できなくてすごく気になったのです。
むしろこう書いたほうがよいのでは、と言う気がする。 Result = *(int *)((intptr_t)pData + 5); intptr_tを知らないなら、適当にintかlongにでも読み替えてくれ。
909 :
841 :2009/07/17(金) 17:45:18
プログラム書いてみたんですが2,3うまくいってないところがあります どこか貼るところありませんか(200行ぐらい)
911 :
841 :2009/07/17(金) 18:01:15
912 :
841 :2009/07/17(金) 18:02:34
>>904 解説をよく読んだらなんか分かったような気がします
分かりやすく丁寧な解説だったので勉強になりました。
重ね重ねありがとうございます。
int a[n][m]と宣言したとき a[i][j] は *(*a + i*n + j) で代用できる という認識は合ってますか?
言いたいことはわかる。でも正しくは *((int *)a + i * m + j) だと思う
>>916 キャストしてint *型のアドレスの足し算だと明示しないといけないんですね。
それと、mとnは間違えました。
回答ありがとうございます。
すごく気になってたので助かりました。
915でも916でも大抵は問題ないだろうけど、 a[n][m]のそれぞれの添え字に沿って*(*(a + i) + j)とするほうがもっといいと思う。
素直に a[i][j] って書こうよ そう書きたくない何か特別な理由でもあるのけ?
メモリ内の配置が(i * M + j)的なのか、(i + j * N)的なのかを知ってると、 a[i][j]をループで回すときCPUキャッシュにヒットしやすいプログラムが書ける
>>920 それってコンパイラの最適化を頼りにしちゃダメなのかい?
きれいなソースだね
924 :
デフォルトの名無しさん :2009/07/18(土) 01:29:48
ファイルから fileinput >> num で値を読み込んだ場合に、 "//"が文字列の先頭に入るとスキップして さらに次の文字列を読み込むフィルタを作りたいのですが、 ifstreamにフィルタを加えるにはどのように記述したら良いでしょうか? iostreamの場合なら以下のようにすれば、コンパイルが通ることが(なんとか)分かりました。 class IOStreambuf : public std::streambuf{/* フィルタ記述 */}; int main(){ IOStreambuf iobuf; std::iostream ioinput( &iobuf ); int num; ioinput >> num; return 0; } ifstreamの場合に以下のようにしてもコンパイルに失敗します。 この場合の簡単なフィルタの作り方をご教授いただけないでしょうか? (とりあえず、コンパイルの通し方だけでも教えていただけないでしょうか?) class FileStreambuf : public std::streambuf{/* フィルタ記述 */}; FileStreambuf filebuf; std::ifstream fileinput( &filebuf ); fileinput >> num;
926 :
デフォルトの名無しさん :2009/07/18(土) 14:16:29
time_t time(time_t *t) って何を意図してこんな形になってるの? time_t* time(time_t *t) なら渡したポインタに埋めてくれるんだろうと思うけどさ
ポインタ型に-1を入れろと
LISPっぽく書きたいから
>>926 引き数はNULLでよいことに注意。
つまり、time_t time(void)でもよかったのだが過去との柵でtime_t time(time_t * t)となった。
930 :
デフォルトの名無しさん :2009/07/18(土) 18:32:47
>>929 NULLでいいのは知ってる
互換性のためか。昔は構造体だったのかね。
931 :
924 :2009/07/18(土) 19:08:33
>>925 とても参考になりました。助かりました。ありがとうございます。
ポンタってどういう意味でしょうか?
きつねの名前か
934 :
デフォルトの名無しさん :2009/07/18(土) 23:18:39
あるクラスが別のクラスをメンバ変数にしてる時に、このメンバ変数をpublicにしちゃってもいいんでしょうか? クラス内の変数を変更するためにアクセサ用意するのも面倒だし、いいかなぁ〜と思ってるんですけど。
普通ラッパーかます
>>934 いいよ
無闇にアクセサメソッド付けてもデメリットしかない
a1からh8なら縦横の位置を出して qが入ると終了する。どうするの?
65個switchすれば?
int x = hoge[0] - 'a'; int y = hoge[1] - '1';
>>935 それはsetterやgetterみたいなのとは違うんでしょうか?
>>936 リソースがきつきつな環境だから少しでもオーバーヘッドあることは減らしたいんですよ。
publicにしちゃおうかな。
MSのMFCなんかだと、よくメンバ変数になってる構造体をpublicにしてますね MFCとか参考にするな?こりゃまたしつれい・・・
マンハッタン・フライド・チキンがどうしたって?
カプセル化のためにとSet〜/Get〜とか書いてたけどさ、これ結局publicにしてんのと変わらないじゃ…と思うようになってきた。
>>944 まぁ、publicよりはマシだと思う。
できれば、只の雪駄下駄ではなく意味のある名前にしてやればいい。
始めまして。最近、C++始めようと思っている初心者なんですけど、質問です。 皆さんオススメの、処理系ってありますか?教えて下さい
たとえば、色のRGBAそれぞれをunsigned charで保持するクラスがあったとして、 いちいちGetRedとかGetBlueとかSetRedとかSetBlueとか書いてたら、 これ結局、自由に弄れるんだからpublicと変わらないんじゃ?と思うんだけどなぁって意味です。
>>948 弄る前にチェックされるとか、弄った結果何も起こらないとか
スレッドセーフにするための同期が行われるとか、
そういうのがなければ、まあそうですね。
単に値を保持するだけだから別にいいよね。 値を変えたからといってすぐに画面に反映させるわけじゃないし、スレッド使う予定もないし。 というわけで、publicでいこうと思います。 ありがとうございました。
>>947 お勧めの処理系とか言われても、何をやりたいのかで変わって来るんじゃね?
言語は何かを成す為の道具なんだから
最終的に Windows上で動作するGUIなアプリケーション作りたいってんなら、最初から WindowsのVCでも使えばいいし、
Linux は詳しくないけど、そっちがいいならそっちの環境用意しないとだし
初心者なので最初はコンソールプログラムから、って話だとしても、最終的にどっちの環境で続けたいかで、
お勧めも変わって来るぜ。 もちろん途中から変更したっていいだろうけど
むしろ、セッターゲッターになんの疑問ももたないやつのほうが、センスが足らないと思う。
すいません。初めてc++をインストールしたのですが・・・・ 初心者のためのサイトからコピペしたものをそのままペーストして ↓ #include <iostream> using namespace std; int main() { cout << "Hello world." << endl; return 0; } とデバッグし hello worldと出たのは良かったんですが 次に #include <iostream.h> void main() { cout << "ああ、"; cout << 20; cout << "歳になると年金を・・・。" << endl; } とコピペをしてデバッグすると前回のhello worldがでるきりで 追加をしたり、新しいプロジェクトを作ったり、先のhello worldの作るときに使ったc++ファイルを 削除したりしたのですが、デバッグすると一向にhello worldのままです。 どうか解決方法を教えてください
確かに単純な構造だったら意味ないしメンドクセーって思う気持ちもわかるが 将来のことを考えてアクセサにしたほうがいいと思うよ
>>950 class Foo {
private:
int value;
Bar *bar;
public:
〜略〜
int getValue() {
return bar->mod(value);
}
};
getValueの中の処理は外からはブラックボックスなので、
こんな風に「何かの処理でモディファイされた値をさりげなく返す」みたいな事も
ゲッターなら簡単。 そして一箇所変更するだけで、これを利用している全てに影響を与える事が出来る。
直のメンバ変数を取り出す形で書いちゃってると、変更があった時、
それを使う箇所全てを書き直さなければならない。 ・・・・っていう観点もお忘れなく
>>951 おまいさんにいうのもなんだが、gccならWin/Linux両立できるお
というわけで、個人的には msys + MinGW ( + vi) をよく利用する
が、初心者向けではない
>>953 なんていうC++インストールしたのか教えて
>>953 C++の何をインストールしたんだ?
VC++ならソリューションエクスプローラーのプロジェクトを右クリックで設定できる
”スタートアッププロジェクトに設定”になってないんじゃないの?
>>953 二回目をコピペしたあと、コンパイルしてないとかそういう
>>955 うーん、そういう用途はちゃんとprivateにしないといけないと思うよ。
でも、ポインタでも参照でもなく単に基本データ型なメンバ変数を操作するSet/Getなら
publicでもいいんじゃないかなっと思うわけなんだ。
こういうときは、プロパティ構文のある言語は便利だと思うね。 さいしょはpublicなメンバ変数にしといて、不都合がおきたら プロパティにすればいいじゃん、クラスを参照してるほうのソースはいじらずにすむんだしー。 でもそういう言語のユーザほど、けっこう「publicメンバ使うな」とかいうんだよなー。 もったいない。
>>960 君の言ってることは逆も言えるよね
単純なアクセスもset/getも変わらないんじゃね?
っていうならpublicメンバ変数にこだわらずにset/getでもいいじゃない
とまあくだらん突っ込みはいいとして・・・
重要なのは『後で変更するかもしれない』ということだよ
たとえば後で参照回数を測定したくなったとしたらどうする?
ソースの該当箇所を全部探して書き換えるのはかなり大変
でも最初からアクセサを用意しておけばこの変更に楽々対応できる
アクセサに1行加えるだけだからね
もちろん参照回数以外の変更にも有効だ
もちろん生でアクセスする明確な理由があるなら生でもいいかもね
もう絶対に変更はしないことが保障されてて
inlineにしても気になるぐらい遅くなって
set/getをタイプするのがたまらなく苦痛だ
とかいうなら生でもいいかもしれない
>>957-959 すいません自己解決できたみたいです。。どうもソリューションのソースファイルに2つ、cppファイルがあったとき
前回のcppファイルのデバッグが優先的に反映されるようになっていたみたいです。
本当に申し訳ありませんでした。
>>963 君はきっと、VCのスレを覗いて来た方がよさそうだ。
>>962 >inlineにしても気になるぐらい遅くなって
クラス内に書くような雪駄下駄に関して言えば、inline指定は無意味。
>>960 どうせなら、publicにした方がいいと思った具体例を出してみなよ。
他人の意見を聞いてみるのもいいもんだと思うよ。
RGBとか座標とか、小物のクラスはpublicでいいし、 普通のクラスでセッターゲッターがやたらとあったら、設計がおかしい。
自分の場合、雪駄では少なくとも入力値がおかしくないかチェックを入れることが多くて、 本当にただ代入するだけのセッタってあまり書いた覚えがない。
座標値なんかも、例えばxとyを常に別々に扱うわけはないからなぁ。 メンバ変数を公開しつつ、void set(int x, int y)なんて雪駄を用意するのもあれだしね。
>>964 メンバ変数を基本データ型で持つクラスがあった時
たとえば、
calss Point{
private:
int x;
int y;
public:
void setX(int x){ this->x = x; }
void setY(int y){ this->y = y; }
int getX(void)const{ return x; }
int getY(void)const{ return y; }
};
みたいなのがあったとして、setでは特に制限もなく代入して、getでは単に返すだけ。
クラス自身は本当に値を保持するだけで何もしない。
privateにしてset/getしてるけど、してることは構造体のメンバに代入してるのと一緒じゃんって思ったの。
じゃあ、set/getはオーバーヘッドになるだけで邪魔なんじゃ…
いっそpublicにしてしまうか?←いまここ
ってな具合です。
それくらいだったら、自分もいわゆる構造体にするなあ。 全メンバpublic(って書くのも面倒だからstruct)、 せいぜい、利便性のためコンストラクタを書くくらい。
オブジェクト指向のカプセル化の概念を壊す 新人プログラマがかってにpublicにし、 熟練プログラマからいやがらせをうけてもしらんぞ オブジェクト指向?なにそれうまいの?だったら Javaは無理 C/C++ で構造体で生き延びろ
>>970 それさ、カプセル化と情報隠蔽がごっちゃになってない?
郷に入れば郷に従えでJavaでは雪駄と下駄を使うでしょ。
あれ、カプセル化は情報隠滅も含むもんなの?
同じじゃないのか? インターフェースと実装を分離して隠すのがカプセル化だろ
>>970 全部のメンバにset/getをつけてないことを祈る
ウチのプロジェクトみたいになorz
実装を考える時って、あくまで 「必要だからそうする」 っていう観点を忘れてはいけない気がする。 丸見えpublicなクラス(むしろ構造体)があった時、それを見たら 「あぁ、これはきっとただの構造体なんだろうな」 と想像がつくし、 全部 getter/setter が定義されてたら、「あぁ、きっと間に何か処理挟む可能性があるんだろうなぁ」 とか思う。 座標とサイズを保持する Rectangle とか、座標を表す Point とか、要は 「ロジック(機能)よりもデータ」 の立場に近い物は クラスというより構造体的で、メンバは丸見えpublicで構わないし、 何かの集合をイメージしてはいるけど、そこにビジタやストラテジが介入するような 「データよりもロジック」 な コンポジションイメージのクラスは、やっぱ値の保障や加工をする事があるので、getter/setter にした方がいい ・・・・ような気がする。 個人的な意見
まったくもってそのとおりだ。興奮した。
本気モードで作るときはちゃんとカプセル化しとけ。 今は直触りで良くても、あとで困るときがある。
ここら辺の話は、”カプセル化 隠蔽”でググったら結構出てくるね。 カプセル化=隠蔽だったり、カプセル化≠隠蔽だったりで解釈?が違うのか。
ただhogeって変数に、gethoge/sethogeって名前つけちゃうのはダメだと思う。 もっと意味のある名前の関数にしる、と統合環境依存症の奴には言いたい。Javaとかで。
しかしJava Beans の命名ルールだと、get○○ set○○ と付けなさい、なんだよな 付けなさいって言うか、リフレクションで自動化する為のルールと言うか
プロパティが使えれば面倒なせったげった考えなくても良さげですが 標準C++は使えないんですか
プロパティってどの言語の話?
C#やVBが持ってるようなプロパティ機構の意味なら、むしろそんな物ある方が独特 てか C++でもオペレータオーバロード使えば似たような処理出来なくも無い やる必要があるかどうかは別として
プロのパンティよりギャルのパンティ。
>>976 べつに困らないよ。
RGBとか座標とかで、直でいじって問題おきたことがない。
ひとりでやる分には どうでもよい
チームでも困らない。
RGBも座標も、纏めてsetすることはないのだろうか。私はset(int x, int y)がないと面倒で嫌なのだが。 つーか、publicで勝手に触られると 最適化もしにくくなるし。 # RGBは元々メンバを分けることが少ない気がするけどね。
>>987 MFCでもJavaでも座標クラスはメンバをpublicにしてるけど、それが問題だって話は聞いたことがない。
>>992 JavaやMFCの座標クラスなんて、自分で見ればいいじゃん。
C++標準の中にもあるじゃないか、pairというもろだし構造体が。 値の集合としての構造体は問題ない。 C++ Coding Standardsにもそう書かれている。 サッター先生より偉い奴はここにはいないだろうから、間違いない。
pairについては分からないが MFC,Javaでの座標の例は? ていうか日本語分かる?
あとで困る例が先じゃないの。
「MFCやJavaの座標クラス」って、例をださないといけないくらいいっぱいあるのか? まあ「Javaの」って言ったら、野良クラスとか含まれるって解釈もあるけど、MFCの ほうは間違いようがないだろ。 もちろんJavaのほうもJDKのやつな。
>>996 あー
>>990 の「たとえば?」は
>>989 の「問題だって話は聞いたことがない」のことを
聞いてるのかな?
「問題だって話を聞いたことがある」に「たとえば?」って問うならわかるけど、
「問題だって話は聞いたことがない」にたとばってって聞いても例は出しようがないな。
それともやっぱり
>>992 のとおり、「MFCやJavaの座標クラスの例」を聞いてるのかな?
pairも知らないし、「MFCやJavaの座標クラス」をなにか別のものと勘違いしてるのかね。
MFCの座標クラスも妙に設定用のメソッドが用意されているよね。 >988の言うのはそのことだろうけど、にも拘らずMFCのメンバはpublicなわけだ。
1000
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。