急速にスレの質が低下してまいりました
STLつかうと一気に実行ファイルサイズが10倍に?!
環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない。
すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
とかいうエラーが出るんだけどこれってどうすればいいの?
#include <stdafx.h>
後氏ね。
言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。
18 :
1:2005/07/01(金) 15:00:10
back_inserterってエロくない?
>>20 std::copy(penis.begin(), penis.end(), std:back_inserter(vulva));
複数の男のチンポを受け入れる女のマンコ(;´Д`)ハァハァ
前スレ
>>992 VisualC++7.1ではそのまま通りました。
よく考え直したら、次のコードで良さそうです:
template <typename lhs, typename rhs>
struct is_equal {
enum { type = false };
};
template <typename T>
struct is_equal<T, T> {
enum { type = true };
};
レスしてくださった人ありがとうございました。
>>23 enumにしなくてもstatic const boolでいいだろうに。
一応書いておく。
次スレは「C++相談室 part43」です。
~~
ふと思ったんだけど、なんでstd::mapにはat()相当のメンバがないんだろうか。
>26
find() がそれに相当するんじゃまいか?
28 :
26:2005/07/01(金) 22:59:23
>>27 いや、そうじゃなくて要素がないときに例外を投げるようなものがないということ。
それにatやout_of_rangeという名前がmapとは多少肌が合わなくても他のコンテナに合わせるということはないのかと思った。
初心者なのですが
文字型を整数型に変換するにはどうしたらいいでしょうか?
atoiは文字列じゃないと使えないようなのですが。
>>26,28
map に at ?
要素が無ければ out_of_range ?
多少とかじゃなくて、激しくキモイよ。
>>29 char c = '9';
とかなら
int n = c - '0';
がらくだな。
>>30 operator[]があるぐらいならat()があってもイイんじゃないの
ってことジャマイカ
33 :
29:2005/07/02(土) 00:04:19
>>31 即レスありがとうございます
早速そのあたり教科書で調べてみます。
getcharって連続しては使えないんですか?
>>34 意味がわかりませんが
c = getchar();
c = getchar();
と書いても何も問題はありませんよ?
36 :
34:2005/07/02(土) 00:22:49
>>35 そうなんですか?すいませんちょっともっかいやり直してみます。
>>33 教科書より文字コード表見た方がいいと思うぞ
getchar()って使ったことないな。
C++標準関数ではないし、一文字だけ入力したいということがない。
>>35のように連続して使うなら、それは文字列として扱った方がいい悪寒:
std::string str;
std::cin >> str;
おっと、こうするとstrに4TBとか入れられてプログラムが落ちるから
C++は危険なんだっけ!
>>38 getcharは<cstdio>のC++標準の関数だけど。
>>38 > おっと、こうするとstrに4TBとか入れられてプログラムが落ちるから
どんなに大きな入力がきても、
str.max_size() まで読み出すか、
最悪 bad_alloc が飛んでくるだけだよ。
それで困るんなら setw(100) とか挟んどけ。
>>39 C標準ライブラリは、参照によって提供されているだけで、
C++標準ライブラリの一部ではないんじゃなかったっけ違ったっけ。
嘘言ってそう、あとで調べ直す(ρ_;)
>>40 スマンちょっとすねてみただけだ・・・
俺が昔試した実装だと、
getchar()やgetc()みたいなものを使って
一文字入力する場合stdioとiostreamでは話にならないレベルの速度差が
あったけどな。
stdioのが10倍程度速かった。ただしマルチスレッドでない場合だが。
nが素数かどうか判定するプログラムってどうやればいいのでしょうか?
>>43 「素数」「判定」あたりでぐぐるといいよ。
>>43 #include <vector>
std::vector<bool> sieve_of_eratosthenes(int upper) {
std::vector<bool> integers(upper + 1, true);
integers[0] = integers[1] = false;
for (int i = 2; i <= upper / 2; ++i) {
int notprime = i;
while ((notprime += i) <= upper) integers[notprime] = false;
}
return integers;
}
bool is_prime(int n){return sieve_of_eratosthenes(n)[n];}
46 :
デフォルトの名無しさん:2005/07/03(日) 03:10:10
いまあるデータの一群を対象に特定の操作(ファイルへの書き込みや読み出しなど)したいとします。
そこでそのデータの集まりをCDataというクラスにします。
今後のメンテナンスを考えるとデータメンバを追加するときに集成するのはこのクラスだけにしたいです。
さらにread/writeというメソッドを追加しファイルへの読み書きができるようにします。
しかし、このCDataのあるインスタンスだけが、read/writeを使えるようにしたいです。
(つまりコードのいたるところで好き勝手にwriteされると言うことを防ぎたい。)
さらにそのread/writeができるインスタンスはデータを読み込んだら他のCDataクラスのインスタンスに
メンバをバイナリコピーしたいとします。つまり、
CDataRW foo1; //こいつはread/writeできる。
CData foo2;
foo1.read();
foo2 = foo1;
foo2.read(); //←ダメ。コンパイルエラーが望ましい
foo1 = foo2;
としたい分けです。よいクラス設計やデザインパターンなどありますでしょうか?
(1) RW 出来るクラス
(2) Rだけ出来るクラス
(3)どっちも出来ないクラス
の3つが作りたいって事か?
>>46の例なら、CDataを派生したCDataRWでread()を実装すればいい。
つーか、
>>47ならCData→CDataR→CDataRWでそれぞれread()とwrite()か。
ご回答ありがとうございます。
そうですよね。結局そういう方法で作りこんでます。
何を嫌がっていたかと言うと、CDataで変数を追加するとCDataRWのread/writeにも同様に修正が必要なことです。
でもそれしかないかなぁ。
最初考えたのがCDataにread/writeを実装して、CDataRWはpublicに派生、CDataNoRWクラスはprotected派生
とやってみたんだけど、それだと
CDataRW foo1;
CDataNoRW foo2;
foo2 = foo1;がダメだったです。コピーコンストラクタを書くと、結局CDataが持っている全メンバの知識が必要になるし。
CData {
protected:
void read_impl() {}
};
CDataRW: public CData {
public:
void read() { CData::read_impl(); }
};
みたいなのは駄目?
あと、コピーコンストラクタは
全メンバを知らなくても
内部でthis->CData::operator =(*other)みたいにすることも出来るけど。
継承が無理ならこんな感じで、クラス内の関数に
最低でもなにもしないwrite()とread()があるとして
template<typename T>
class CDataOpen {
T & impl;
bool writable;
public:
CDataOpen(const T& d,bool b=false) : impl(d) ,writable(b){}
size_t operator()(){return b ? impl.write() : impl.read();}
};
func(){
CDataOpen<CDataRW> Write(fool,true);
CDataOpen<CDataR> Read(fool);
CDataOpen<CDataRW> Read2(fool2);
while(...){
...処理内で使いまわす
Read2();
Read();
Write();
}
}
ありがとうございます。
>this->CData::operator =(*other)
こういうコピーもありましたか。
const CDataRW & CDataRW ::operator=(const CData & o)
{
this->CData::operator=(o)
return *this;
}
って感じでしょうか?
ちなみにprotectedで派生させたCDataNoRWがあるとした場合、
CDataRW drw;
CDataNoRW dnrw;
drw = dnrw; //コピー
dnrw = drw; //逆のコピー
だとすると
const CDataRW & CDataRW ::operator=(const CDataNoRW & o)
const CDataNoRW & CDataNoRW ::operator=(const CDataRW & o)
が居るのでしょうか?
const CDataRW & CDataRW ::operator=(const CDataNoRW & o)
{
this->CData::operator=(o)
return *this;
}
としてみたところ、
error C2243: '型キャスト' : 'const CDataNoRW *__w64 ' から 'const CData &' の変換は存在しますが、アクセスできません。
となってしまいました。CDataNoRWをいったんCDataにしたいですね。。ポインタだったらdynamic_castが通用するのかも知れないな。。
と言うわけで、このパラダイムをC++の世界ではどう扱うのかに興味が移ってきました。
(製造は簡単な
>>48さんの方式を取りたいと思います。)
その形式でダウンキャストが必要になる、というのは、
つまり引数側(代入式の右辺側)が派生クラスということでしょ?
だったらそれこそ何もしなければ代入できると思うけど。
もちろん、データメンバを追加していた場合には
スライシングの問題が起きるけどね。
(逆に、Base::operator =() を利用する時は、追加したメンバを初期化する必要がある)
>>48 いや、こうだろ。
CData
↓ ↓
CDataR CDataW
↓ ↓
CDataRW
55 :
52:2005/07/03(日) 09:41:48
よく分らなくなってきました。勉強して出直します。
56 :
48:2005/07/03(日) 12:48:03
57 :
デフォルトの名無しさん:2005/07/03(日) 15:32:12
プログラミングは全くの素人ですが、
諸事情でC++使えるようになりたいんです。
毎日勉強したら何日くらいでマスター出来ますか?
個人差あるのはわかってますけど、だいたいの目安を教えてください。
>>57 まずは「マスター」するとはどういうことか示してもらおうか。
>>57 そんな無意味な質問をすることから推測するに、一年くらいやれば
糞設計のメモリリークしまくりオブジェクト指向とは無縁の糞コードを量産できるようになります。
60 :
デフォルトの名無しさん:2005/07/03(日) 15:59:41
C++(VisualStudio6.0)で書かれたソースをC++.NETで開き、文法上のエラーを解消し、
ビルドしたところ、以下のメッセージが出てしまいました。
error LNK2001: 外部シンボル ""char * __cdecl fgets(char *,int,struct _iobuf *)" (?fgets@@$$J0YAPADPADHPAU_iobuf@@@Z)" は未解決です。
該当するソースはこのようになっています。
FILE *fstream;// ファイルディスクリプタ
char tLine[256];// 一行読み込み用
if( fgets( tLine, 128, fstream ) == NULL ){
if( ferror( fstream ) ){// 一行読み出しエラー
break;
}
break;// EOFに達した
}
その他,atoi、strstrなど、Cランタイムライブラリ関数(?)関連のものは
みな外部シンボルが未解決と出るんですが…何か参照設定が足りないのでしょうか?
ご教授いただければ思います。
62 :
デフォルトの名無しさん:2005/07/03(日) 16:20:13
>>61 スレチガ失礼しました。誘導ありがとうございます。
すみません。初心者なんですが「コマンドラインから引数を受け取る」ってどうすればいいんでしょうか?
>>63 int main(int argc, char* argv[])とすればargvに入る。
詳細はググれ。
どうでもいいけど、
>char tLine[256];// 一行読み込み用
>if( fgets( tLine, 128, fstream ) == NULL ){
これはひどいな。
>>63 #include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
for (int i (0); i < argc; ++ i)
cout << argv [i] << endl;
return 0;
}
適当で悪いけどこれ↓ってobjectCには何が入るの?
struct structA{ ... }strA
class classB{ ... }
classB *objectC = (strA*)
ぜんぜん意味分らん
>>60 目を覆いたくなるコードだな…
バッファが256なのに128読み込み
それにfstreamはstd::fstreamと混同しそうで怖いな
漏れはCはサッパリだが、Cだとbreakつかいまくりなの?
>>68 structAでoperator classB()とかをオーバーロードしてあるのかな
>>70 breakつかってもif文から脱出できるわけではないから、あれは
外側にループがあるんだろう
>>68 「適当」じゃなくて「ちゃんと」書けよ
classB *objectC = &strA;
の間違いか?
>60
それはVC++の質問じゃなくて
標準C++固有の質問なんでしょうか。
>>73 むしろC++ですらなく、Cの質問の悪寒。
void f(ifstream& fin) {
string line;
while (getline(fin, line)) {
// ...
}
};
くだらない事のですが相談にのって下さい、悩んでいます
同じclass Interfaceを基底クラスに持つ、class Fooとclass Baaがあり、
クライアント側はInterface型のリストとしてFooとBaaを所持すると言う、ありがちな関係があります。
さて、FooとBaaのデータを、ファイルに保存する必要があります。
人に読んでもらう事が前提のフォーマットです。
ここではたと迷ってしまいました。
Baa BaaDataA BaaDataB ...
Foo FooDataA FooDataB ...
Baa BaaDataA BaaDataA ...
といった感じの、先頭にタイプIDみたいのがあるフォーマットならば
いかにもオブジェクト指向っぽく扱えて楽なので、これで行こうと思っていました。
ところが世間のファイルフォーマットを観ると
Foo
FooDataA FooDataB ...
Baa
BaaDataA BaaDataB ...
BaaDataA BaaDataB ...
こんな風に、FooならFooでまとめて記述しているフォーマットが多く
確かに見た目はこちらの方がスマートですし、データ量も少なく、ベストな気がします。
ところが後者を実装するとなると、Interface型のリストしか無い以上
小細工が必要になり、あまり嬉しくありません。
どちらが良いか、なんでもいいのでアドバイス頂けると幸いです。
1行1レコードなら、map<string, vector<string> >にいったんシリアライズし
["Foo"]と["Baa"]について順次書き出す
読むときはまとまっていた方が嬉しいが、Interafceの生成順は保持しなくてもいいの?
77 :
75:2005/07/04(月) 17:22:05
はい、序列を表に出すようなデータではないので順番は全く構いません。
さすがに1行では無理なのですが(例が悪くて申し訳ないス)、
なるほどmapを使ってstringの代わりにオブジェクト自体を持たせれば…
おかげでスマートな実装が見えてきました
> 読むときはまとまっていた方が嬉しいが
にも後押しされました。ありがとうございました。
>>77 stringの代わりにオブジェクト自体、はあんまりかも。ポリモフィズムの意味が薄れるから。
class Interfaceに純粋仮想関数 serialize() を用意し、
その返値を pair<string, string>とかにして、各派生クラスで:
pair<string, string> serialize() {
string str = ...;
return make_pair("Foo", str); // strは"FooDataA FooDataB ..."
};
template <typename T, typename S>
void serialize(T first, T last, S& container) {
while (first != last) {
pair<string, string> data = (*first++)->serialize();
container[data.first].push_back(data.second);
}
};
vector<Interface*> interfaces;
map<string, vector<string> > serial_map;
serialize(interfaces.begin(), interfaces.end(), serial_map);
もっといい書き方がありそう
>>78 うっかり、multimapにpair<string, Interface*>を持たせてソートし
Interfaceに持たせたsaveData()=0を一気に使わせるようなのを考えてました。
お手本ありがとうございます。書き方も含め勉強になります。
>>75 の例では断然上を取るがな、俺は。
下の良さってのは、領域が節約できることだけだ。
上の例はgrepやawkのようなツールでも扱いやすいし、
セーブやロードも単純化できる。
>>80 もしwindowsでいえばコマンドプロンプトのアイコンを見たことがあるユーザを対象にするなら
Foo FooDataA FooDataB...
形式を選んだ方がいいかもしれない。
出力をソートすればidごとにまとまるし、grepで必要なidのだけ見れる。
ログを「加工」する部分は外部ツールですべきだとも思う。
でも、各種ツールを使うスキルを要求するのは難しいし(というより不可能)
ログがそのまま人間にとって読みやすくないと見てすらもらえない(ρ_;)
だから、
Foo:
\tFoo1:
\t\tFooData1A FooData1B
\t\tFooData1C FooData1D
\tFoo2:
\t\tFooData2A FooData2B
Baa:
\tBaa1:
とか、見やすく、プログラムからも扱えるような形式のがいいかなと。
xmlではき出せばいいのかな。そこまでするものなのかな。
class C1 {
// 省略
}
class C2 {
template <class T>
void F(T t = C1());
}
template <class T>
void C2::F(T t) {
// 省略
}
というコードで、
C2 c2;
c2.F(C1());
だと問題なくコンパイルされるんですが、
C2 c2;
c2.F();
だと「could not deduce template argument for 'C1'」というエラーが出ました。
デフォルト引数でテンプレートを推論する事はできないのでしょうか?
>>82 コンパイラの立場で質問。
c2.F();と書いた場合に、
引き数のない関数の呼び出しとディフォルト引き数つきの関数の呼び出しの区別はどうすればいい?
84 :
82:2005/07/06(水) 16:22:57
>>83 c::F(T t)はオーバーロードされてないんですが、呼び出しの区別に困るとはどういうことでしょう?
>引き数のない関数の呼び出しとディフォルト引き数つきの関数の呼び出しの区別はどうすればいい?
区別のしようがないからエラーにしていいんじゃなかったっけ?
デフォルト引数の中身を評価するのは、オーバーロード解決後なんじゃない?
c2.F<C1>();
これならさすがに通るな。
俺もメンバテンプレートをいまいち理解できてねーな。
89 :
82:2005/07/07(木) 10:02:13
>>86 オーバーロードを解決するのに関数の実体化が必要だけど、デフォルト引数の評価はこの時点ではできないため、
テンプレート引数が不明で関数の実体化ができない、みたいな感じなんでしょうか。
>>87 デフォルト引数では無理ですか。
皆様ありがとうございました。
>>89 まぁ、デフォルト引き数は何かと問題になるから引き数の違いでコンストラクタを複数作るほうが無難だね。
しかも、>82の例だとそれがデフォルトコンストラクタになるのだから尚更。
#逆に、デフォルトコンストラクタを作りたくないとなると話は別だが。
std::list の関数って何故全てが安定的になっているんですか?
今リストの勉強してるので気になります。
class CPOINT {
public:
CPOINT(int x, int y) : x_(x), y_(y) {}
int x_, y_;
};
struct SPOINT {
int x_, y_;
};
void F1(CPOINT cp) {
...
}
void F2(SPOINT sp) {
...
}
CPOINT cp(0, 0); // OK
SPOINT sp = {0, 0}; // OK
F1(CPOINT(0,0)); // OK
F2(SPOINT(0,0)); // エラー
F2(SPOINT({0,0})); // エラー
F2(SPOINT() = {0,0}); // エラー
F2(SPOINT{0,0}); // エラー
F2({0,0}); // エラー
コンストラクタが定義されていないと、
初期化した一時オブジェクトを作ることができないのでしょうか?
SPOINT sp = {0, 0};
これがOKなだけに、なんか納得できない・・・。
>>92 当たり前じゃん・・・・
それから、
SPOINT sp = {0, 0};
これはC++とは関係なく、Cでも出来る、構造体の初期化にすぎない。
C99には複合リテラルがあるが果たしてC++で使い物になるかどうか。
寧ろ、Cとの互換性のために残されたって気もする。
96 :
デフォルトの名無しさん:2005/07/09(土) 00:28:38
>>92 class CPOINT
{
int x_, y_;
};
F1(CPOINT(0,0));
↑これも通らないと納得いかないのか?
初心者の「納得行かない」はただ単に理解してないだけだよな
>>91 意味がわからない。
「安定的」でないほうが自然な関数を例に挙げてもらえるとわかるかも。
質問させてください。
二次元配列(4x4)に、変数を含む値を代入しようとしています。
{X,0,0,0},{0,X,0,0},{0,0,X,0},{0,0,0,X}
のような形です。ここで、Xは宣言の段階では決定していないので、
Xが決定した後に値を代入したい と思っています。
宣言時以外の時に、まとめて代入はできないのでしょうか?
初心者丸出しですが、どなたか教えてください・・・・
>>98 二次元配列を二つ用意し、一つは
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1,
で初期化しておく。
その後Xが確定したときにもう一つの方に
for (int i = 0; ...) {for (int j = 0; ...) {theArray[i][j] = X * fixedArray[i][j];}}
とでもしてコピーすればいい。
#つーか、std::copy()か。
ゼロ梅しといて
for (int i = 0; i < 4; ++i)
a[i][i] = X;
でいいだろ
>>98 {} は初期化の構文なので定義のときしか使えない。
C99でC言語に導入されたコンパウンドリテラルなら {} を使った値を「代入」で使える。
でもこれは標準C++には無い機能だ。
おとなしく要素ごとに代入するコードを書いてしまうのがいいよ。
ところで98が宣言はブロックの先頭に限らないことを知らないという可能性はないのか?
103 :
98:2005/07/09(土) 14:25:20
レスありがとうございます
>>99 なるほど、そういわれてみればそれもアリですね
>>100 いや、全部埋めるわけではないので・・・
>>101 なるほど、やはり初期化の構文なのですね
>>102 大丈夫です。それは知ってます。
というか、今はその方法で乗り切ってます。
for文の中でXを決定し、それに沿った形で行列を定義する
プログラムなのですが、1回1回forの中で変数を作るのも
ちょっと気持ちが悪かったので、forの外で作った変数を
繰り返し利用できないかな と思った次第です。
>>103 パフォーマンス上の問題でも無い限り、メンテナンス上の問題を優先する意味で
変数はなるべく狭いスコープで定義(および初期化)することをお勧めする。
106 :
92:2005/07/09(土) 16:52:36
>>93 Cには一時オブジェクトがなかったから、
{}による初期化は宣言時の初期化用にしか作られていないということですかね。
>>96 それは
CPOINT cp(0,0);
も
F1(CPOINT(0,0));
も通らないという意味で、92で納得いかないと思ったこととは違います。
メンバ変数を順に初期化するコンストラクタをコンパイラが書いてくれたら便利だとは思いますけど。
レスありがとうございました。
ほらやっぱりクラスと構造体の違いを理解してないだけじゃん
勉強しろ
>>107 は?「クラスと構造体の違い」って、デフォルトのアクセス指定だけだろ?何を勉強しろって?
そうそう。
俺は構造体にもよくコンストラクタをつける。
このスレ質落ちすぎ。
低下してまいりました。スレの質が。急速に。
>>108 >何を勉強しろって?
オブジェクト指向。自分一人でC++だけ触ってりゃいい人は楽でいいですね。
設計上の概念と言語要素をごっちゃにするなよ…
class{をstruct{private:に書き換えたところで何も変わらんだろ。
設計上の概念が違うのに実装上では同じように書けなきゃおかしいと?
違う概念なんだから実装が違ってあたりまえだと思うのは普通じゃないのか。
>>112 煽られたからってテキトーなこと言ってんじゃねーよ。
>92の質問は些細な言語仕様についてのもので、オブジェクト指向の概念とは関係ないだろ。
>>114 それは曲解だ。
異なる設計上の概念が同じ言語要素に対応することが「あっても良い」と
言っている。
コンストラクタがあると{}で初期化できないって
やっぱ規格で決まってんのかなあ
>>115 オブジェクト指向の為に導入されたクラスの記述方法に
オブジェクト指向の概念は必要ないと?素晴らしい支離滅裂ぶりですね。
あと断っておきますけど構造体にコンストラクタのようなものが書けるようになったのは
オブジェクト指向におけるクラスにコンストラクタという概念があったからですよ。
逆もなきゃおかしいなんて無茶な事言わないで下さい。あくまで構造体が拡張されたんです。
つまりデフォルトのアクセス指定だけが構造体とクラスの違いなわけですね ;-)
>>119-120 あんた>107で>112の人だよな?
煽られたからってテ(以下略)
たとえばC99のコンパウンドリテラルが使えれば
>>92の問題は解決するわけだが、
C++にそれが存在しない理由は、オブジェクト指向の為ではない。
同様に、たとえば
>>106の言う「メンバ変数を順に初期化するコンストラクタ」を
C++コンパイラが自動生成してくれない理由も、オブジェクト指向の為ではない。
つまり>92がオブジェクト指向を学んでも
「なぜC++ではこのような記述ができないのだろう」
という疑問の答えがそこに見出せるとは思わない。
あとな、C++スレで「クラス」といえば class で宣言されるアレで、
「構造体」といえば struct で宣言されるアレだと思うに決まってるだろ。
それとは別に自分で定義した意味があるんなら、
区別できるような呼び方にして、その意味をちゃんと説明しないとうまく伝わらないよ。
「構造体とクラスの違い」の意味するところだけど、
みんなどれのことを言ってるの? 俺混乱してきた('A`)
A. structキーワードを使ったときとclassキーワードを使ったときの違い
B. 「構造体」という概念と「クラス」と言う概念の違い
C. その他
煽りあってる奴全員がそのへんごっちゃにして書いてるからダラダラ続くんだろ。
int* p;の時の*(p+1)とp[1]が違うか同じかっていう議論に置き換えてみたらどうよ
ふつうのブラジャーとフロントホックブラの違いも、アクセス権の違い
ということでよろしいでしょうか?
「ふつうのブラジャーとフロントホックブラの違い」の意味するところだけど、
みんなどれのことを言ってるの? 俺混乱してきた('A`)
A. 着け方の違い
B. はずし方の違い
C. その他
D. 脱がし方の違い
童貞の戸惑い方の違い
いやいや、外し方一つとっても両手で外すか片手で外すか、或いは口で外すかの違いがあるぞ。
>口で外す
なんだかキモイ
ぶらじゃーってきもちいいよね。癖になるぅ〜。
質問です。
template<> Complex absolute<Complex>(Complex c) {return Complex(c.getAbs(), 0));}
の template<> Complex absolute<Complex> とは何なんでしょうか?
普通テンプレートの宣言は template<typename T> T absolute(T t){ ......... return t }
だと思うのですが。よろしくお願いします。
>>132 クラス自体がテンプレート宣言を持たないメンバテンプレート。
136 :
132:2005/07/10(日) 20:04:08
なるほど、特殊化というのですか。
汎用的なテンプレートを特定の型用に定義しなおす場合に使うということですね。
参考になりました。thx
137 :
デフォルトの名無しさん:2005/07/11(月) 17:42:09
もしかして配列へのconst参照は存在しない?(VC++7.1)
#include<iostream>
#include<typeinfo>
int main()
{
typedef char (&ref_array)[100];
typedef const char (&cref_array1)[100];
typedef const ref_array cref_array2;
typedef ref_array const cref_array3;
std::cout << typeid(ref_array).name() << std::endl; //char [100]
std::cout << typeid(cref_array1).name() << std::endl; //char const [100]
std::cout << typeid(cref_array2).name() << std::endl; //char [100]
std::cout << typeid(cref_array3).name() << std::endl; //char [100]
char a[100];
ref_array ref = a; ref[0]='A'; std::cout << ref[0] << std::endl; //A
//cref_array1 cref1 = a;cref1[0]='A'; std::cout << cref1[0] << std::endl;//compile-error
//cref_array1 cref1 = a;(const_cast<ref_array>(cref1))[0]='A'; std::cout << cref1[0] << std::endl;//damage-error(dangerous)
cref_array1 cref1 = a;(const_cast<char*>(&cref1[0]))[0]='A'; std::cout << cref1[0] << std::endl;//A
cref_array2 cref2 = a;cref2[0]='A'; std::cout << cref2[0] << std::endl;//A
cref_array3 cref3 = a;cref3[0]='A'; std::cout << cref3[0] << std::endl;//A
}
>>137 そもそもtypeidで参照型は取得できないんじゃないの?
クラスをネストするとき、内側のクラスから外側のオブジェクトにアクセスするのは
どうやるんでしょうか。
class outside {
int x;
class inside {
void func() { x = 0; }; // x is not a member of outside::inside
};
};
xをoutside::xにしたり、friend class outside;つけたりしましたがダメっぽいですよ。
class outside {
int x;
class inside {
void func(outside *o) { o->x = 0; };
};
};
とか
class outside {
int x;
class inside {
outside * const o_;
inside(outside *o) : o_(o) {}
void func() { o_->x = 0; };
};
};
とかってこと?
つーか、目的にも拠るがoutsideを継承するかoutsideのmenmberとしてinsideを持つかじゃないのかねぇ。
insideのインスタンスを作るのに、別にoutsideのインスタンスは要らないのだから、
何か渡されないとアクセスしようがないではまいか。
144 :
デフォルトの名無しさん:2005/07/11(月) 22:12:22
>>139 何故それでアクセスできると思ったの?
javaかなんかと混同してない?
>>139 >xをoutside::xにしたり、friend class outside;つけたりしましたがダメっぽいですよ。
friend class inside; だが。
>>137 なんで存在しないと思うの?
typedef char array[100];
typedef array const& cref_array;
この cref_array では
>>137の言う「配列へのconst参照」とは違うのか?
次期C++で取り入れられる予定のtypeofは、リフレクションのような感じか。
148 :
137:2005/07/12(火) 07:13:45
>>146 typedef char array[100];
typedef array const& cref_array4;
//cref_array4 cref4 = a;(const_cast<ref_array>(cref4))[0]='A'; std::cout << cref4[0] << std::endl;//crash
const_castでクラッシュしたからそう思った。(勘違いなのかバグなのか)
>>148 #include <iostream>
int main()
{
typedef char array[100];
typedef char (&ref_array)[100];
typedef array const& cref_array4;
char a[100];
cref_array4 cref4 = a;(const_cast<ref_array>(cref4))[0]='A'; std::cout << cref4[0] << std::endl;//crash
return 0;
}
ふつうに 'A' が表示されて終了したよ。(cygwin g++ 3.4.4)
なんで const_cast してるのかもよくわからんな。
>>148 VC7.1でやってみたがクラッシュしなかった
>>148 VC7.1でやってみたがクラッシュした。
int main()
{
char a[100] = {0};
static_cast<char (&)[100]>(a)[0] = 'A';
}
これでも落ちた
template <class T>
char (&foo(T& t)) [100]
{
return t;
}
int main()
{
char a[100] = {0};
//static_cast<char (&)[100]>(a)[0] = 'A';
foo(a)[0] = 'A';
}
これだと落ちない
VCで155のコードを実行すると0x00000000を読もうとしたと出るが、
aを初期化しないでやると0xccccccccを読もうとして落ちる。
余計に参照剥がしをしているみたいだ。
バグか。まあいいやもうすぐ2005出るから。
159 :
デフォルトの名無しさん:2005/07/13(水) 00:09:15
禿しくフケたな・・・ www.research.att.com/~bs
'A';
↑毒男に見えた・・
161 :
デフォルトの名無しさん:2005/07/13(水) 00:28:39
艶がダライアスの WAVE みたい
質問です。
std::string から const char* に変換するときに c_str() メソッド
を使う必要がありますが、なんとか省略する方法はないかと悩んでます。
別に省略しなくても処理の上で不都合はないんですが、
一々書くのめんどいよな、というのが理由です。
で、自分なりに方法を考えてみてるんですが、
1)std::string に operator const char*() を実装する
←ビルドする環境全てに手を加えないといけない。移植性が低下する。
2)std::stringを派生させて、そのなかで operator const char*() を実装する。
←無理。std::stringのデストラクタがvirtualで宣言されてないから
(Effective C++ 14項)
3)std::stringクラスの実装をコピペしてクラス名を変えて
その中で operator const char*()を実装する。文字列処理には
そのクラスを使う。
←gccのライブラリに付いてる<string>は、GPLで配布されてるから
ソース非公開のプログラムには使えない。ソース非公開な
プログラムで改変利用OKな実装があれば解決。
4)std::string代替クラスを自力で作って、operator const char*() を実装する。
文字列処理にはそのクラスを使う。
←自力で処理を実装しなくても std::string() に処理を委譲するとか
すれば、デバッグの必要も無い。
他に方法が無いなら 4) で行こうかなと思ってます。
スマートな解決法があれば教えてください。
163 :
デフォルトの名無しさん:2005/07/15(金) 13:33:33
>>162 漏れなら単に .c_str() を一々付けて使うけど、それがどうしても嫌なら
class cstring : public std::string {
public:
あれこれコンストラクタを定義
operator const char*() { return c_str(); }
};
で済ませる。このケースで virtual dtor なんかいらない。
>>162 おいらはstd::stringをprivate継承して
usingでメンバーファンクションをエクスポートかな
operator const char*()はc_strを使う
>>163 あ、それで良かったんですか。
派生するときには無条件にデストラクタをvirtualにしないと
いけないような気がしてました。今Effective C++読み直してみたら、
「子クラスのメンバが解放されないことがあるからデストラクタ
をvirtualにすること」って書いてたので、どうやらこのケースだと
問題なさそう。これで逝きます。Thx
>>164 using云々がちょっと分からない。privateにする必要も無い気が…
でも返事ありがd
private なら std::string* s = new mystring; って出来ないから delete s; が安全ってことじゃない?
using はただ private メンバを持ってきてるだけだと思うけど
あーでもこの場合private継承しなくともコンポジットでいけるから
確かにprivateにする必要ないかもね。漏れもよく分からん。
>>167 using の方が全ての転送関数を書くよりもほんの少し楽。
おれはコンポジション派だが。
趣味でC++/WinAPIで組んでて、UNICODE使うのにも踏み切れず、
std::string で1バイトずつ2バイト文字かどうか判別しながら使ってるんだけど、
こんな場合例えば std::string::find() とかの2バイト文字対応版みたいなのはどう作るべきかな。
グローバルとか適当なネームスペース内にただの関数として作るとか、
継承して作るとか考えてみたけど、find(str, "hoge") は str.find("hoge") って書きたいし、
普段使うときは std::string で使いたいから、継承するのもコピーしたりのコストがかかるし。
何かしら我慢するしか無いんだろうか…。
>>169 そういうのはchar_traitsを自分で書けばいい。そしてtypedefする。
class my_char_traits {};
typedef std::basic_string<char, my_char_traits> mbstring;
あるいはstd::char_traits<unsigned char>を特殊化してもいいかもしれない。
171 :
164:2005/07/15(金) 18:28:55
>>168 >using の方が全ての転送関数を書くよりもほんの少し楽。
意図してたのはこれです
>>165 class my_string: private std::string {
typedef std::string Base_;
public:
my_string (const char *p): Base_ (p) {}
operator const char*() {return c_str ();}
using Base_::size;
};
こんな感じで必要なメンバ関数をエクスポートしていくと引数
返値の型をいちいち写す必要がないのでちょっと楽かと思います
ちなみにおいらもc_str派
C++ロケールはグローバルロケールを汚染しない?
>>162 俺の場合、c_str()を呼ぶのは関数の引数に渡す場合が1番多いから、
5) 必要になるたびに関数をオーバーロードする。
自作の関数でなければ自分の名前空間に入れて、usingせずに使っている。
namespace hoge
{
inline BOOL TextOutW(HDC hdc, int nXStart, int nYStart, const std::wstring& str)
{
return ::TextOutW(hdc, nXStart, nYStart, str.c_str(), static_cast<int>(str.length()));
}
}
>>162 Exceptional C++のitem39に全く同じ質問があるな
>>173 .c_str()を書く手間を省きたいだけで、関数ごとにそれだけ書くのは耐え難いんじゃないか?
実際には、レガシーなポインタを受けるような関数を使うときは、
何らかの理由で自分でラッパを書くことが多いから、オーバーロードは手間でないのかもしれないが。
// 例えば
>>173のコードだと、HDCをメンバ変数に保存するようなファンクタを書くなどで
// 結果的にオーバーロード自体を行う必要があり、ついでにラッパの引数はstringで受けるように
// 書けばよい、など。
なんでchar*への変換オペレータを提供してないか考えれば
c_str()を書く手間など
177 :
デフォルトの名無しさん:2005/07/15(金) 23:17:43
178 :
デフォルトの名無しさん:2005/07/16(土) 00:34:34
実験で使う器具名、その製造会社・型番・製造番号を入力し
それを器具名でexitと入力されたらそこで終了というプログラムを作りたいのですが
どうやって終了させれば分かりません。
どなたか教えてもらえないでしょうか?
char data[4][20];
while(data[0] != "exit"){
printf("器具名を入力してください(exitで終了)->");
scanf("%s",data[0]);
printf("製造会社を入力してください->");
scanf("%s",data[1]);
printf("型番を入力してください)->");
scanf("%s",data[2]);
printf("製造番号を入力してください->");
scanf("%s",data[3]);
printf("\n");
}
とてもC++には見えんのでstrcmpあたりかな。
180 :
178:2005/07/16(土) 00:37:33
すみません。日本語むちゃくちゃでした。
実験で使う器具名、その製造会社・型番・製造番号を入力し
それをループさせてexitと入力されたらそこで終了というプログラムを作りたいのですが
どうやって終了させればいいのか分かりません。
どなたか教えてもらえないでしょうか?
>>180 スレタイを百回声に出して読め。
それでも分からなかったら回線切って首吊って氏ね。
>>181 分からなかったから回線切ります。マジで。
なんかもうどうでもよくなってきたよ…。あーなんでこんなに働かなきゃいけないんだろ…。
仕事でそれかよ。
お前の人生テラヤバスw
人間と一緒にいるのが嫌になったんだお
逝ってきますね
おー、逝ってらっしゃい。
ここもネタスレになったか・・・
187 :
デフォルトの名無しさん:2005/07/16(土) 07:46:44
>>181 何でだよ、178 のプログラムは ISO/IEC14882 で明白に認められているれっきとした C++ プログラムたりうるぞ
おまえこそ規格票を百回声に出して読め、それでわからなかったら回線切って首吊って氏ね
またこのゴネ方か。
>>187 > 何でだよ
printf/scanfはC++では用いられないことが多く、178は<cstdio>をインクルードしたようではない。
となるとCだと想像される。
stringstreamが使いづらいのでCString::FormatやAnsiString::sprintf使うような人がいることも忘れないでください
191 :
デフォルトの名無しさん:2005/07/16(土) 10:57:48
>printf/scanfはC++では用いられないことが多く、
ソース
>178は<cstdio>をインクルードしたようではない。
ソース
>となるとCだと想像される。
あ、ソースか
ほとんどアッパーコンパチに近いんだから何だってありだが、
まぁ他にC言語のスレはたくさんあるんだから、あえてこのスレを選ぶなら
C++の質問のほうがふさわしい。
193 :
デフォルトの名無しさん:2005/07/16(土) 11:05:41
だから「C++」とは何かをはっきりさせなさいよ
ISO/IEC14882 が定義する範囲じゃないんですか
俺も、このコードは「Cのソース」だと思うが
俺自身もC++でstdioを使いまくることもあり、「向こう行け」とは言えないのも事実。
そして何より、最近はCとC++の区別をつけずに
いきなりC++から入る人も多いため、どこまでがCの範囲かわかっていない人も多い。
が、それでもやっぱり「C++スレ」向きじゃないと思う。
>>193 なにを持って「このスレでのC++」の意味合いとするの?
・住人の多数決の多いほう?
・このスレの
>>1 の意見?
・part1の
>>1 の意見?
君が常識的に考えてそう思うのならそれで良いのでは?
printf, scanf は C++ でもあるだろうけど、C の一部
でもあるんだからCスレでやるのが一番なんじゃないの?
C++ 固有が少しでも入ってたらここでやるってのでいいんじゃない?
今回は181が馬鹿なのと
かといって178が擁護するほど意欲が湧く質問じゃなかったというだけの話
199 :
169:2005/07/16(土) 13:49:34
>170
d。なるほど、そんな手もあるのか。
よく考えたら find(str, "hoge") がダメで「std::string」を使う上にコピーがダメとなれば、
参照を持つクラス作って hoge(str).find("hoge") くらいしか書きようが無いな。
とりあえず char_traits とか試してみる。
200 :
デフォルトの名無しさん:2005/07/16(土) 14:12:35
>>197 >>194 の指摘はふまえた上での発言か
C++ と被る言語は C だけではない
どの言語とも被らないことの証明は悪魔の証明
ここよりも妥当なスレがあると主張する者に
そのスレの具体的なアドレスを示して誘導する挙証責任があり、
かつ誘導された者がこのスレでも話せることを別スレで話すかどうかは任意
ジャヴァに似てるっすね
はーーーっはっは
所詮はできそこないの言語よ
>>203 お前は所詮できそこないの人間だけどな。
別にC++でコンパイルできようと、Cスレがあるんだから、
そっちが適当ならそっちへ行くべき。なんだっけか、
「特別法は一般法に優先する」みたいな。
てかC標準までここで扱ってたら
Cスレ要らないじゃん
207 :
デフォルトの名無しさん:2005/07/16(土) 22:00:02
帰れ
209 :
デフォルトの名無しさん:2005/07/16(土) 23:33:10
なぁ、
public:やprotected:にstaticメンバがあるのはわかる。
private:なところにstaticメンバを作るのってどういう意味があるんだ?
そのprivate:のstatic でかつ、constをつけた場合とそうでない場合の意味を教えてくれ。
・Singleton
・他に見られたくない定数
>>210 アクセス指定と、 static にするかしないかは関係ないだろ。
privateのstaticなんて何に使うんだよ、って意味じゃなくて?
>>213 private を使う場面と、 static を使う場面が重なれば private の static になる。それだけだろ。
組み合わせたから特別な意味になるわけじゃない。
さらに const も同様。 >210 は何かを誤解してるんじゃないかと思う。
外部に晒したくないけどクラス内で共有したい情報なんていくらでもあるだろ
やはり
>>210はstaticメンバが何なのかまるでわかってないに一票
>>216 オブジェクトを生成しなくても利用できるメンバだろ?
static変数に限って言えば、存在範囲が限定されないオブジェクト。
privateでstaticってのはわかるよ、そりゃ分かる。
どんなときに使うのか、シングルトンみたいな具体例を示してくれってことだ。
オレにいくら、そもそもstaticとは何か、なんて言っても無駄だ。
あーっていうか、もう解決してんだけどさ。
>>211の時点で。
スマートポインタとかそんなとこだろ。
例えば
class MyString {
static char null;
const char *data;
public:
MyString(const char *s): data(&null) {
if (s && *s) {
data = new ...;
...
}
}
};
みたいなのとか、いくらでもありそうな気がするけど。
ム板は回答者にエスパー能力が必要とされるからな。
回答者のレベルが低い場合もあるにはあるが、
>public:やprotected:にstaticメンバがあるのはわかる。
の一行が意味無いっつーか余計で全体の文がワケ分からなくなってる。
クラス属性って何ですか?
3年B組の属性はどんな感じでしょうか?
熱血:
友情:
背徳:
憎悪:
230 :
デフォルトの名無しさん:2005/07/17(日) 20:44:05
C++初心者なんですが…。
ファイルの一覧を取得したくて下記のfindfirstを使ったのですが引数の*filespecって絶対パスでなければ使用不可能なんでしょうか。
MSDNには「ターゲット ファイルの指定 (ワイルドカードも使えます)」なんて書いてあるんですが、
ためしに相対パスを使用したらEINVAL(Invalid argument)が返ってきちゃいました。
みなさんは相対パスで指定したいときってどうされていますか?
そもそも相対パスなんか使わずに、まず絶対パスを取得して、その後findfirstを使用するのが一般的なんでしょうか。
ご教授ください。
long _findfirst( char *filespec、struct _finddata_t *fileinfo );
232 :
デフォルトの名無しさん:2005/07/17(日) 21:05:33
>>230 あくまで C++ の範疇での回答だが・・・
その「相対パス」とやらを、画面に表示してみてはどうだろう
文字列を渡す関数でトラブったときの常套手段で、ものすごく初歩的なミスにがっかりできたりする
誘導&アドバイスありがとうございます。
ちなみに相対パスをコンソールに出力したところ
"..\\Work"
と想定どおりのパスが表示されました。
もちろんディレクトリ未存在ってことはないんですが。。。。
ちなみに絶対パスでは動作確認できました。
>"..\\Work"
これは想定どおりなのか…?
235 :
デフォルトの名無しさん:2005/07/17(日) 22:02:42
ATL では DLL か EXE を出力しますが OCX はだめなのでしょうか?
何を 言って るんだか 分か りません
237 :
デフォルトの名無しさん:2005/07/17(日) 22:24:03
Windowsでの質問なんですけど。
Unicodeでの1文字の表現でどうすれば良いんでしょうか?
asciiだと以下のような感じの場合unicodeだとどうすればよいのか
char hoge = 'a';
WCHAR hoge = 「ここがわかりません」
238 :
デフォルトの名無しさん:2005/07/17(日) 22:27:34
char:きゃー
wchar:うきゃー
俺詠み
241 :
デフォルトの名無しさん:2005/07/17(日) 22:31:24
>>239 ああ、それで理解するのですか。
どもでし。
ヒント:サイバイマン
>>237 少なくともC99とかだと\u表記が使えるみたいだな
ソースのエンコーディングを限定していいのなら、
L"あああ"
とか書ける。この辺はコンパイラ依存。
多国語対応が必要 & \u表記が使えないんなら、
wchar_t c = 0x2359;
とか
wchar_t s[] = { 0x1234, 0x2345, 0 };
とか書かざるを得ないだろ
16bit のフルアダーをビット演算だけで作る方法を教えて下さい。m(_ _)m
よくわからんがこんなか?
unsigned short
fadd_bit(unsigned short x, const unsigned short b) {
if (x & b) {
x = fadd_bit(x, b<<1);
x &= ~b;
} else {
x |= b;
}
return x;
}
unsigned short
fadd(unsigned short x, unsigned short y)
{
while (y) {
unsigned short yy = y&~(y-1);
y ^= yy;
x = fadd_bit(x, yy);
}
return x;
}
テストしてないが全ビットいっぺんにやってみた
typedef unsigned short T;
T fadd(T a, T b)
{
while (b) {
T carry = a & b;
a = (a | b) ^ carry;
b = carry << 1;
}
return a;
}
249 :
デフォルトの名無しさん:2005/07/18(月) 13:14:58
おまえら、アレだ。
C++で名前空間と例外をうまく使わないと
糞プログラムだぞ。
>>247 thx です。
でもyとyyのところがよくわららナイッす。
while (y) {
unsigned short yy = y&~(y-1);
y ^= yy;
は
for (unsigned short bit = 1; bit!=0; bit <<= 1) {
yy = y & bit;
と等価と考えていいですか?
>>247 全加算機実装するのに引き算を使ってるのはいかがなものか
252 :
246:2005/07/18(月) 14:08:12
typedef unsigned short T;
T fadd2(T a, T b)
{
while (b) {
T carry = a & b;
a = (a ^ b);
b = carry << 1;
}
return a;
}
これで目的のものができそうです。thx all
floatやdoubleの符号を低コストで変える方法ってあるのでしょうか
符号付き整数型ならば、確か一番上のbitを上げ下げするだけで可能だと、習った気がします
今は単に
float f;
f *= -1.0f;
とかやってます
>>253 コンパイラがその程度の最適化もできないとお思いか。
下手の最適化休むに似たりじゃ。いや最悪状況が悪くなる場合まである。
>>253 f = -f; としてやれば、まともなコンパイラなら一番低コストな方法に
変換してくれる希ガス。
>>253 整数だって同じだぞ。
最上位ビットの上げ下げで済むならコンパイラがそうするってことで
そういうコードを書けってことではない。
大体2の補数だとそれじゃダメだ。
(´-`).。oO(Gems3に色々載ってたな……)
ていうか一番上のビットの上げ下げで符号を変えれるのはむしろfloatとdoubleだろ。
まぁ、そんなコードをコンパイラに頼らずに一々書くやつは抹殺したくなるが。
>>257 C++ Gems? 3なんてあったっけ? とかいってみたり
260 :
253:2005/07/18(月) 15:13:14
皆さんありがとうございます
257さんが気になりますが、コンパイラに任せて255さんのやり方でいきます
floatなのが気になって眠れない……
ゲーム屋とかじゃないの?
あのさ、特定のプログラムがUnicodeに対応しているかを取得する方法ってあるの?
バージョン情報じゃないみたいだし、
検索してみたけど検索キーワードがヘタレなのかヒットしない (;´Д`)
いっそのこと、ファイル名のOEM外の文字を"_"とかに置き換えようかな・・・。
Unicodeに対応しているという言葉の意味が不明なのでなんともいえない。
そもそも環境依存の話ならスレ違いだが。
OEMという言葉からしてWindows固有の話っぽいな
>>264, 265
VC++のスレだと思い込んでました(゚∀゚;) 逝ってきま
>>266 DependencyWalkerでUnicodeAPI呼んでるか見たら?^^;;;
268 :
デフォルトの名無しさん:2005/07/19(火) 21:16:56
親1、子多数で、子がまた親になりうる様な、
そんな一般的なTree構造を実現しているtemplateのうち、
比較的標準のものがあったら、教えて頂けないでしょうか
Compositeパターンでググれ
例えばCompositeパターンを実装するにしても
いくつか共通のメソッドが出てくると思うのですが(addChile的やシーク関連等)
その辺のtemplate(!=パターンの)があればなと
271 :
デフォルトの名無しさん:2005/07/20(水) 16:02:10
配列の参照ってどうやったら引数に取れるのか教えてください。
*&charで宣言はいいんだが、呼び出し側の記述がワカラソ…
>>271 template <int N>
char (&array)[N] とか。BCCだと通らんぞ。
BCCだとそんなのすら通んないの?
274 :
271:2005/07/20(水) 17:01:00
ごめん、言ってる意味がわかんなかった。出直してくる、
普通に
void f(char (&array)[20]);
で取れるが。呼び出すときは、
char x[20];
f(x);
276 :
デフォルトの名無しさん:2005/07/20(水) 17:07:15
いやいや、あらは初新車に難しいだろ〜と
吹き込む2ch宗教だから。
*(onagai_mite + 3); でおk;
「c 参照渡し」とかでぐぐれ。
と、静観してたヤシが言ってみる。
>>271 g++/bccでテスト。
#include <all> // :P
void f(int* const & array) {
for (int i = 0; i < 10; ++i) array[i] = i;
};
int main() {
int array[10];
f(array);
for (int i = 0; i < 10; ++i) cout << array[i] << endl;
}
>>278 違うかもしれんw
スマソ、配列を使うことがない(万が一使うとしてもnewしてポインタを受け取る)ので
ANSI/ISO IEC14882見ながら適当に書きました。
一応、reference to pointer版:
void f(int*& array) {}
int main() {
int* pointer_to_array_of_int = new int[10];
f(pointer_to_array_of_int);
};
配列の参照ってなにいってんの?
ただのintへのポインタの参照じゃん
int* p = nullpo;
f(p);
単にポインタと要素数の2つか、あるいはイテレータをfirstとlastの2つを引数にとればいいんじゃないか?
なぜわざわざcharの配列に限定するのかわからんな
string使え。string&で受け取れ。書き換えないならconstをつけろ。
>>280 配列への参照と、配列の先頭アドレスへのポインタへの参照は別物だぞ
283 :
デフォルトの名無しさん:2005/07/20(水) 20:42:40
とはいえ、プロも歳をとれば油断する。
大事故になりかねない。
若い奴でも調子に乗ればとんでもない殺人を犯すことになる。
プロでも酒を飲めば3人の高校生の命を奪ってしまう最近の交通事故のように
なることもありうるのだ。
JR西日本のような列車事故は焦ったために起きたことだ。
焦りに焦ってバグで人を殺すようなプログラミングをすることは許されない。
私はC++を医療器や航空機に使うことは反対だ。
C++は使い方を誤ると誤って患者や旅客の命を奪いかねない言語だからだ。
だから人の命を奪う恐れが高いC++は普及させないほうがいいと思っている。
時間とかければいいとはいえ、顧客は容赦しない、
「他の言語でやすくできるならなぜC++では安くできないのか?」
と問いつめてくるのだ。そうなると大抵の企業はものを「お客様は絶対的な神様だ」と称して
ものを速く完成させようとすると。すると徹夜残業が増える。徹夜残業しても間に合わないので
C++にしかできないとんでもないスパゲティコードが生まれる。
そしてC++のコードが世に増えれば増えるほど無駄に徹夜する時間が増えてしまう。
C++のコードを貰い受け、引き継ぎ、苦労する後継者が増える。
そして焦りが人の命を奪う。
だから、私はC++だけで作られた自動操縦システムを開発することに反対する。
JR西日本のような列車事故を二度と起こさないためにも。
少なくともC++に厳重なルールとC++の規格が統一されるまでは
C++は普及させないほうがいいだろう。人々の命を救うためにも。
void array_callee(int (&array)[10]) {
cout << sizeof array/sizeof array[0] << endl;
for (int i = 0; i < 10; ++i) array[i] = i;
};
void array_caller()
{
int array[10];
cout << sizeof array/sizeof array[0] << endl;
array_callee(array);
for (int i = 0; i < 10; ++i) cout << array[i] << endl;
}
void vector_callee(vector<int>& array) {
cout << array.size() << endl;
for (int i = 0; i < array.size(); ++i) array[i] = i;
}
void vector_caller()
{
vector<int> array(10);
cout << array.size() << endl;
vector_callee(array);
for (int i = 0; i < array.size(); ++i) cout << array[i] << endl;
}
285 :
デフォルトの名無しさん:2005/07/20(水) 22:14:50
string string_rep() const; // Expression of character string
void char_rep(char s[]) const; // Expression of C style character string
286 :
デフォルトの名無しさん:2005/07/20(水) 22:20:09
よく分かります
>>284 そこはこうしようよ。
template<typename Iterator>
void array_callee(Iterator first, Iterator last)
{
cout << distance(first, last) << endl;
for (int i = 0; first != last; ++first, ++i)
*first = i;
}
template<std::size_t N> inline void array_callee(int (&array)[N])
{
array_callee(array, array + N);
}
inline void vector_callee(vector<int>& array)
{
array_callee(array.begin(), array.end());
}
288 :
284:2005/07/21(木) 00:42:58
289 :
デフォルトの名無しさん:2005/07/21(木) 12:33:43
void f( int* i ); と void f( int i[] ); って同義でしょ?
つまり配列の参照は使い道がないってことでOK?
>>289 >void f( int* i ); と void f( int i[] ); って同義でしょ?
は確かにそのとおりだけれど
>つまり配列の参照は使い道がない
はなぜ?
>>291 横レスだけど、配列って元々値渡しじゃないうえ、outパラメータにも
ならないわけだから、積極的に参照を使う理由に乏しいような気がする。
295 :
デフォルトの名無しさん:2005/07/21(木) 13:41:51
template <class T, unsigned N>
void print_array(const T (&t)[N])
{
for (unsigned i = 0; i < N; ++i) {
std::cout << t[i] << std::endl;
}
}
せめてこのくらいは思いつかないの?バカ?
>>295 そのケース、参照にしてると何が嬉しいのか教えてください。
釣りにマジレスカコワルイ・・・ orz
>>296 例えば、
template <class T>
void print_array(const T* t, unsigned N)
{ ... }
int n[10];
print_array(n, sizeof(n) / sizeof(n[0]));
ってやるより100倍楽だろうが
マジで脳みそ腐ってんのか?
配列の参照になんの意味も感じないんだったら使わなきゃいいじゃん
template <class T, unsigned N>
void print_array(const T t[N])
{
for (unsigned i = 0; i < N; ++i) {
std::cout << t[i] << std::endl;
}
}
>>298 なんでわざわざ参照にしたの?
>>300 残念ながらそれは
コンパイルが通らなかった。(VC++7.1)
まあ確かに
>>298は有効なコードだ。
わずかcountof(n)の数文字書かずに済むだけの
メリットだが。
>>300 値を書き換える場合を考えたに決まってるだろボケ
つかなんなんだよその糞コード
呼び出すときに
print_array<int, 10>
とでもやれってか?
人間の手を煩わせないようにコンパイラに出来ることをやってもらおうと
してんのにそんなあほらしいこと出来るか
なるほど。参照にしとくとコンパイルが通る、というのが
配列の参照を使うメリットか・・・
実践的価値は高いが、なんだか納得いかんような。
>>302 配列の値を書き換える???
例示してみてください。
>>304 template <class T, unsigned N>
void nullpo(T (&t)[N])
{
for (unsigned i = 0; i < N; ++i) {
t[i] = 0;
}
}
こういうことだろ?
307 :
289:2005/07/21(木) 14:22:41
まあ結局使い道がないことだけはわかった。
>>300のコードって規格外じゃないの?
gccでも通んなかったし
いやだから300のコードはポインタを引数に取る関数を宣言しているんだってば
template <class T, unsigned N>
void print_array(const T *t);
Nって何wワロス
312 :
309:2005/07/21(木) 14:42:18
あ,違う.微妙に説明間違った.
300のコードは関数呼び出しに伴うテンプレートパラメータ推論の際に
引数の配列に対して配列->ポインタの暗黙の変換を試みるために,
結果として呼び出しが無効になる,というべきなのか.
人の話を聞くと結論を変えなきゃいけないから
耳を塞ぐことにしたみたいだしね。
// numberofマクロの置き換え
template<typename T, std::size_t N> inline std::size_t numberof(T (&)[N]) {return N;}
これって関数だからランタイムに評価することもありうるんじゃないの?
コンパイル時に定数になってる保証あるの?
319 :
デフォルトの名無しさん:2005/07/21(木) 15:29:00
WinXP SP2 VC++6.0です。
マシンが2台あります。(仮にA,Bとします)
マシンAのComnというフォルダが共有されており、Bからアクセス可能です。
この共有フォルダ内にあるアプリのexeファイルがあります。
Bからこのexeをキックし、Aのマシン上のプロセスとして動かしたいのですが、
プログラムでそのような制御は可能でしょうか?
調べたところ、起動したいアプリがサービスなら、OpenSCManager(),OpenService()
などを使えば起動できるようなのですが、サービスではないので…。
320 :
_/ ̄|○#:2005/07/21(木) 15:46:01
あの〜はじめてここにカキコするんですけど・・・
消せないファイルがあるんですけどどうやったらいいんでしょうか?
教えてください_| ̄|○
>>319 ShellExecute()でリモートパス渡してできればナイスだがやったことない
>>316 ない。でも保証を求める必要もない、かもな。
よほどのヘボ処理系でもない限りは定数になるから。
>>322 一度使ってみろよ。
int a[10];
int b[numberof(a)];
が通るか?
もしも複合リテラルがあれば、std::vectorにtemplate<size_type N> vector(const value_type (&)[N]);なんてコンストラクタを作って
std::vector<int> v = (int []){1, 2, 3, 4, 5};なんてことができるようにするのに使えるんじゃないかと思う。
>>319 -srvany.exeを使ってサービスにする
-マシンAのTelnetサービスを有効にして、そこから起動する
-マシンA上で動作し、適切な通信を受ければexeを実行する
(トロイの木馬的)サーバプログラムを常駐させる
-適切なスレで質問する>Visual C++かWindowsプログラミングかそのあたり?
共有フォルダ上の実行ファイルが、リモートでそのまま実行できたら、
セキュリティホールになりそう。
>>array
特に配列でなければならない理由がないのならば、標準ライブラリのコンテナを使え。
>>325 マジで?コンパイラ何?
つーかそれが定数になるのは
最適化を通すからだろ?
あり得ない話だ。
328 :
デフォルトの名無しさん:2005/07/21(木) 16:41:02
%27.20eの時より多く小数点が表示されるのって何がある?
329 :
319:2005/07/21(木) 16:42:12
ありがとうございます。
ShellExecute()で、実行するファイル名を"\\xx.xx.xx.xx\\xxx.exe"としてみたんですが、
ローカルで実行されてしまいました。
どうやらこの質問はスレ違いみたいですね。
もうちょっと調査してみます。
>>323 コンパイル時定数であることと,コンパイル時に定数(即値)に最適化されることを
ごっちゃに議論するのはまずくないですか?
CMAGAZINE 3月号の"ゲームのシクミ"の一部で、
class CTask
{
・・・
void* operator new(size_t t);
・・・
};
とあるのですが、これをコンパイルすると
void*の行で " ) が必要 "とエラーになります。
その行をコメントアウトするとコンパイルできます。
(Borland C++ 5.5.1使ってます)
見たところおかしくないと思うんですが、なぜなんでしょうか。
教えてください。
「…」の部分がなんだか知らんが、
class CTask
{
void* operator new(size_t t);
};
これはコンパイルできた。VC++.NET2003
333 :
331:2005/07/21(木) 18:12:57
おかげさまで解決しました。
class CTask
{
void* operator new(size_t t);
};
でコンパイルできない!
class CTask
{
void* operator +();
};
でできるのに!と思ったら、#include <iostream>
してませんでした。これやったらコンパイルできました。
そこでsize_tを定義してるのかな。
borlandだから起きた現象なのですか?
(わざわざインクルードしなきゃいけない事。)
size_tはたぶん<stddef.h>とか<sys/types.h>とかで定義されてると思われ
335 :
デフォルトの名無しさん:2005/07/21(木) 18:19:21
size_tはstddef.h(またはcstddef)
336 :
335:2005/07/21(木) 18:20:51
すまん、被った。
class Class_1 {
int *m_pnData;
public:
Class_1 () : m_pnData(NULL) {}
~Class_1 () { Delete(); }
void NewData (int nNum) { m_pnData = new int[nNum]; }
void Delete () { delete [] m_pnData; }
};
class Class_2 {
Class_1 *m_pcObject;
int m_nNum;
public:
Class_2 () : m_pcObject(NULL) { m_nNum = 0; }
~Class_2 () {
for (int i = 0; i < m_nNum; i++)
m_pcObject[i].Delete();
delete [] m_pcObject;
}
void Create () {
m_nNum = 2;
m_pcObject = new Class_1[m_nNum];
m_pcObject[0].NewData(3);
m_pcObject[1].NewData(3);
}
};
メモリの開放で迷ってます。
↑のプログラムはClass_2のデストラクタで、Class_1のDelete()を呼んでるのですが
これで開放できてるんでしょうか?
どなたかお願いします m(__)m
>>338 Class_1::Delete ()
にプローブでもいれて確かめては?
す、すいません。
>>337のは実行したらエラーでます orz
もうちょっと考えてみます。
スレ汚し、どうもすみませんでした m(__)m
>>338 m_pcObject[i].Delete();
これでClass_1::m_pnData[]が解放され、NULLポインタになり、
delete [] m_pcObject;
これでClass_1のデストラクタが呼ばれ、Class_1::Delete()が呼ばれ、NULLポインタの解放
(何も実行しない)が行われる。
Class_1のデストラクタで、生成したオブジェクトを解放しているなら
あえてDelete()メソッドを用意する意味はないと思われる。
同様のことがNewData()メソッドにもいえて、これはコンストラクタでやるべき処理では。
ソースは一部を抜粋してるだけだろうから、一概にいえないけど。
ところで、std::vectorは使いたくないの?
342 :
341:2005/07/21(木) 19:33:11
などと自信満々に書いたけど、delete[]はNULLポインタだと例外だっけ
if (m_pcObject) {
delete[] m_pcObject;
m_pcObject = NULL;
}
とするか、二重解放しないように
for (int i = 0; i < m_nNum; i++)
m_pcObject[i].Delete();
を消すかしないとダメか。
いずれにせよ、NewData()もDelete()メソッドも、コンストラクタ/デストラクタにすべきだと思うよ
>>341 おお、なるほど。
newでコンストラクタが呼ばれるように、
deleteでデストラクタも呼ばれるんですね。
初めて知りましたww
Class_2のデストラクタは、
m_pcObject を deleteするだけでよかったのかぁ。
std::vectorは、勉強不足でわかりません orz
丁寧なご説明、どうもありがとうございました。
delete でデストラクタがちゃんと必要数分呼ばれるように
hoge = new class; delete hoge;
hage = new class[array]; delete[] hage;
と区別してるわけで
345 :
341:2005/07/21(木) 19:52:23
仕様が不明なのでできるだけ忠実にstd::vectorで書くと:
class Class_1 {
vector<int> m_Data;
public:
Class_1(const int& n) : m_Data(n) {}
};
class Class_2 {
vector<Class_1> m_Object;
public:
Class_2(const int& n) {
m_Object.push_back(Class_1(3));
m_Object.push_back(Class_1(3));
}
};
こうか?
int *pData = NULL;
int array = 5;
pData = new int[array];
if (array == 1)
delete pData;
else it (array > 1)
delete [] pData;
>>344 どうもです。
普段はarrayを↑みたくフラグっぽく使ってるんですが、
もっとカッコよく開放できる方法って知ってます?
>>345 うう、わからないー。
どもすみません orz
てゆか、
>>345はすげーかっこいいww
それで開放できてるんですか。
347 :
344:2005/07/21(木) 20:04:19
>>346 new の時に [n] と書いたら、たまたま n が 1 だったとしても delete[] で通してる。
言葉的に 「オブジェクト配列を確保」(でも1個だった) と 「オブジェクトを確保」とを区別したい ってことかな。
>>346 STLのお勉強をしなさいな。std::vector。
だいたいどのC++の本でも標準コンテナの使い方は載ってると思う。
あれ?
一個だけの確保でも、
delete []
していいんですか?
アフォな質問ですみませんが。
>>348 はい、がむばります。
これが噂のコンテナってやつかww
>>346 p = new T[..] で確保したなら、...のトコが1でもdelete [] p; で開放できる。
一々 if 分なんかで区別する必要はないです。
>>350 おお、次々と新事実がww
私の手元の本には、
[] を使うと配列で確保できる
開放する場合も [] を使う
としか書いてないです・・。
今ちょっとためしてみましたが、一個のヤツを [] で開放しても
エラーとかはでないようですね。
どうもありがとー。
>>351 C言語的配列 ≠ C++語的配列
foo = new T;
hoge = new T[1];
は似ているようで違う。 (最適化で同じになるかもしれんが、本質的に違う機能だ)
○ new T; delete T;
× new T; delete[] T;
× new T[]; delete T;
○ new T[]; delete[] T;
353 :
341:2005/07/21(木) 20:43:31
>>345 Class_2(const int& n) {
この引数のnは不要だった。次のコードにしようかどうか迷って消し忘れた:
Class_2(const int& n) : m_Object(n, Class_1(3)) {}
>>351 new T[0]とした場合、要素数0の配列が作られ、戻り値は非NULL値になることにも注意。
あと、実行時エラーがでるかどうかで正しいかどうか判断するのはやめれ(´д`)
最近、実行時引数argvから:
double d = atoi(argv[3]);
としているコードを見たが、これまでそのプログラムが正しく動いていたとはとても思えない。
vectorでclear()しても確保されたメモリは解放されないというのは
本当ですか?解放する方法は無いんですか?
>>353 >double d = atoi(argv[3]);
何が問題?
勿論argcが4以上として。
>>355 double 型の変数に整数を入れてはいけません教の人なんだと思う。
それはそれでわからんでもないが、何故それがでてきたのやら。
>>354 > vectorでclear()しても確保されたメモリは解放されないというのは
>本当ですか?
実装依存だが、大抵は本当
>解放する方法は無いんですか?
swap
>>354 vectorは、効率のために、保持しているオブジェクトの数以上のメモリを確保している(capacity)ので
実装によってはメモリを「完全に」解放しきらないかもしれない。
>>355 argv[3]は実数値を指定する(実際には0<=d<=1の値を受け取る)仕様で、
ここでatoiで常に0か1を返していても実行時エラーはでないが、正しく動作していないと思われる。
エラーがでるかどうかで正しいコードかどうか判断することは危険だという例示のつもりだったけれど
説明不足すぎてわかんないなスマソ
>>359 だめだスレ追いきれねぇ。
なんで double d = atoi(argv[3]); が出てきたんだ?
361 :
341:2005/07/21(木) 21:20:19
>>360 マジでスマソ、atoiの件は忘れてくれEEEEE 最悪な例えだった!!
>>353 の "実行時エラーがでるかどうかで正しいかどうか判断するのはやめれ"
の例として
>>353 の実体験で
実数値を指定するargv[3]に対し double d = atoi(argv[3]); としている奴が居た。
という
>>353 以外絶対分からない例を挙げた。
この流れでOK?
363 :
341:2005/07/21(木) 21:27:19
>>362 その通りであります。漏れにしか絶対分からない例を挙げてすいませんでした。
スレ汚しすいませんでした。
そろそろスレ常駐を終わり帰るます(´д`)
364 :
デフォルトの名無しさん:2005/07/21(木) 23:02:49
申し訳ないのですがPHPで2次関数の解を出すプログラムを教えてください。
ax2+bx+c=0 の解です。
PHPで
366 :
デフォルトの名無しさん:2005/07/21(木) 23:14:18
はい。 お願いしますm
>>364 好きな方法を使いたまえ。
1. 解の公式
2. Newton法
3. Laguerre法
以上のどれかをPHPで実装すること。
俺はPHPは知らんがどの言語でもアルゴリズムあってのものなので。
以上。
PHPのスレへいけばいいじゃない。
369 :
デフォルトの名無しさん:2005/07/21(木) 23:40:57
あざーす!
>>325 あーそれ、たぶんコンパイラの拡張だから。 gcc かなんか使ってるんじゃない?
--
#include <cstddef>
template<typename T, std::size_t N> inline std::size_t numberof(T (&)[N]) {return N;}
int a[10];
int b[numberof(a)];
--
・gcc -pedantic
:4: error: ISO C++ forbids variable-size array `b'
:4: error: variable-size type declared outside of any function
・msvc
(4) : error C2057: expected constant expression
(4) : error C2466: cannot allocate an array of constant size 0
>>341 delete してもポインタ変数の値は変わりません。
>>342 ヌルポインタに対する delete は「何もしない」で正解です。
372 :
370:2005/07/22(金) 01:23:40
ちなみに、現行の規格でも numberof(a) をコンパイル時定数として使える実装は存在する。
>>372 それって
int f(){
static const bool b = false;
if(b){
return;
}
else{
return 0;
}
};
が通ったりするの?
だとすると、便利とは思うけど
やりすぎな気が。
374 :
デフォルトの名無しさん:2005/07/22(金) 16:07:17
メンバ内でのコンストラクタの明示的呼び出しって
どうやるんでしょうか?
operator=( hoge());
こうやるしかない?
375 :
デフォルトの名無しさん:2005/07/22(金) 16:36:40
Visual C++ .NET Standard 2003 を買おうと思っているのですが、
これって商用利用可能でしょうか?
マイクロソフトのサイトを見たのですが書いてないのです。
あと、「C++ならこれより他のツールがいいよ」とかありましたら教えてくれませんでしょうか。
スレ違いでしたらごめんなさい。
>>374 new (this) hoge();
this->~hoge()を呼び出さずに動かした時にどうなるかは知らんが
>>373 それ、 if(0) return; else return 0; でも通らないだろ。
コンパイル時定数とは関係無い。
378 :
デフォルトの名無しさん:2005/07/23(土) 15:14:52
変数を宣言するときは、使用する直前にしたほうがいいって聞いたんですけど、
ループの中とかでもいいんですか?
for(){
int x;
…
}
int x;
for(){
…
}
どっちが良いんだろ(゚д゚)
前者の方が当然いいに決まってる
もしintがユーザー定義型でコンストラクタに時間がかかるのであれば
最適化という意味で後者の書き方をするときもある。
変数のスコープは短い方がいいよ
極稀にforとかifとかの中でしか使わないような
変数も全部ひっくるめて関数の最初で宣言しろ
っていう変なオッサンがいるけど、相手にしないように
C99より前のCであってもブロック作れば関数内の任意位置で変数宣言できるわけだが。
それに C99 でなくとも if や for でも変数宣言出来るわけだが。
>>383 Cでもこういうことやっちゃうからね
void hoge(void)
{
…
{ /* ココでローカルスコープ (1)*/
…
}
…
{ /* ココでローカルスコープ (2)*/
…
}
}
386 :
デフォルトの名無しさん:2005/07/23(土) 18:49:23
デストラクタでメモリを解放(delete)しているようなクラスがあるのですが
これを静的なインスタンスとして確保した場合は、
アプリケーション終了前に、デストラクタとは別の手段で
明示的にdeleteを呼び出す必要が有るんでしょうか?
ないお
必要ないだろ、
つーか、どうやってdeleteするつもりだ。
それはそうと、アプリ終了時にデストラクタが呼び出されるかどうかも怪しい。
> アプリ終了時にデストラクタが呼び出されるかどうかも怪しい
使用時にリークさえなければ、終了時の処理は適当で良いって事かワーイ
>>387-389 STLに例えると、必要ないのに明示的にclear()を呼び出す感じのを考えていました。
ありがとうございます、気にせず行きます。
391 :
デフォルトの名無しさん:2005/07/23(土) 19:30:12
>>386 どうやってアプリを終了させるつもりか知らないが、mainの後には当然デストラクタが呼ばれる。
すべての変数は、関数の最初で宣言されるべきだ、と主張する変なオッサンに理由をたずねたい。
PTSDか何かだろうか?
自動変数がプリミティブ型ばっかりで
関数の規模が大きくなければ別にいいんじゃねとか思う
「すべて」って言うのならPTSDかそれともいい加減古くなってガタがきてるかのどっちかだろ。
全部の変数が使用される直前になってから宣言されてるコードも読みたくないけどな
>>392 Cでこんな風に書く奴少ないだろ、
>>385。
C++での途中宣言のメリットとほぼ同じ効果が得られるにもかかわらず。
それと同じ。
途中宣言止めるべきとは俺は言わないが、自分のスタイルを変えるほどの
インパクトが途中宣言にはない。それだけ。
昔case文ごとに同じ名前の変数宣言してドツボにはまった俺様が来ましたよ。
それくらいのことでそんなに見通しが悪くなるようなコードを日々生産しているのか?
俺がCではなくC++を選択したのは、「メモリの仕様効率をよくしたい」
などの理由ではなく、むしろその辺を犠牲にしても「保守性をあげた
い」などの人間にとって管理しやすい点を重視したから。
「後からみたときに、および他人が見たときにどちらが分かりやすい
か?」と考えから、俺は先頭で宣言するスタイルを選択した。
「”for(i”・・・iって宣言したっけな?」などとソース全体を見渡すのが
面倒だから。
for(int i;...を使えよw
>>399 保守性を考慮すればこそ、使用箇所での宣言を取るべきだろ。
ヒント: 399はC99を使えない環境かもしれない。
昔は#define for if(0) else for とかやったもんだ。
405 :
デフォルトの名無しさん:2005/07/24(日) 14:23:31
処理系の特徴への対応方法の基本をさておいて変なマクロに走るクソガキうぜえ
#define for if(0) else forに文句言う奴がいるとは
どうもこのスレでは、日本語の不自由な香具師がageる傾向にあるようだな。
>>405 処理系の特徴への対応が変なマクロになるのはよくあることだろ。
一瞬のうちにフクロにされる>405ワロス
411 :
デフォルトの名無しさん:2005/07/24(日) 14:36:52
>>408 変なマクロに「しちまう」奴がよくいるだけ
本当に必要なケースはまれ
>411
具体的にどうぞ
413 :
デフォルトの名無しさん:2005/07/24(日) 14:59:19
>>412 for のスコープなんて
int i;
for(i = 0; 〜
でいいんだよ
for(int i = 0;
が使いたくなる心理はあるが
想定要件よりも優先することなどない
むしろ旧仕様とわかっている処理系で
マクロにしてあるから for(int i = 0; を使えと言われる方が強い抵抗を感じる
(この心理もコーディング基準より優先しないが)
俺は富豪派
>>413 マクロが使ってあっても前者の書き方は許されるだろ。
必要ない場所では後者で書くように言われるかもしれないが、
それは「マクロにしてあるから」じゃないだろう。
想定要件って?
417 :
デフォルトの名無しさん:2005/07/24(日) 15:37:44
たとえば互換性の範囲
for if(0)〜のマクロ使えば互換性も可読性も両立できるじゃん。何がしたいの?
419 :
デフォルトの名無しさん:2005/07/24(日) 15:42:37
要するに『心理的に嫌だからfor if(0)...のマクロは使わない』ってことですね。
どっちにしろ気をつけなければいけないのだが...
自分はスコープ最小原理主義者です。
#include<iostream>
struct I
{
int i;int j;int k;
I()
{
int j;//後から変数を宣言するのは気をつけよう
{int i=100;//深いスコープでは重複に気をつけよう}
{ j=100;}
{ k=100;}
}
};
int main(){I i;
std::cout << i.i << std::endl;
std::cout << i.j << std::endl;
std::cout << i.k << std::endl;
}
422 :
デフォルトの名無しさん:2005/07/24(日) 15:56:55
>>420 道具をスペックどおりに使うというだけのこと
必要でないギミックは使わないのが基本だよ
クサッ
このスレ超臭い
俺もそう思う。
長い関数を書きたがるところでは切実な問題なのかなw
>>422 それはそうだ。あとは意識の問題。
VC6でプログラミングしているのか、
C++でプログラミングしているのか。
必要でない限り環境に依存させないのも基本だろうと思うので、
後者を基本とするべきじゃないか?
それでも、VC6にはそれを否定するだけの負のポテンシャルがあるのは認める。
427 :
デフォルトの名無しさん:2005/07/24(日) 18:32:38
自分のPCのIPアドレスを取得する方法を教えてください。
「PC」も「IPアドレス」も、標準C++の仕様には含まれていませんが
127.0.0.1
431 :
デフォルトの名無しさん:2005/07/24(日) 18:54:55
ワラタ
::1
>>427 実際自分のIPアドレスってのは常に複数あって
宛先などからルーティング情報などによって選択されるので
単に「自分のIPアドレス」といっても何が適切か分からん品
勉強した上でネットワークプログラミングスレあたりで。
433は433で的はずれな気がする
スレ違いにレスしている時点でなんだが
436 :
デフォルトの名無しさん:2005/07/24(日) 19:32:51
親クラスのポインタに子クラスのアドレスが入るじゃん?
で、そのポインタから子クラスのメソッドが使えちゃったりはするはずないよな?
公開メソッドならどこからでも使えるわけだが何か
>>436 仮想関数をオーバーライドしたものなら使えるだろ。
dynamic_castすると・・もう親クラスのポインタじゃないから関係ないか
>>435 どっか内容間違ってる?
まあこのスレに書くことが間違いってのならそうだが
>>440 うーんとね、前半の3行くらいがちょっと。
最後の一行はごもっとも。
いつか自分にもIPアドレスが振られる日が来るんだろうか・・・
赤紙みたいで嫌だな
>437
>438
それで安心しました。thx
445 :
デフォルトの名無しさん:2005/07/24(日) 21:04:44
いま電話があって俺がバイクで事故を起こして警察に捕まったらしい。
しかも相手が妊婦で流産までさせてしまったそうだ。示談にするから
金振り込めっていうし電話の向こうで俺は泣いてるし、いったい俺は
どうしたらいいんだ
448 :
445:2005/07/24(日) 21:13:35
電話の向こうで泣いてる俺が来ましたよ
んな超有名なコピペに反応せんでも…
char[] hoge
このメモリに、あるファイルの完全パスの文字列が割り当てられています。
このパスの2階層上のフォルダパス文字列を
CString型の変数に割り当てる処理を行おうとしております。
Ex)”C:\test\test1\hogehoge.cpp” -> "C:\test"
C++で上記処理を行う場合、どのような処理方法が一般的なのでしょうか?
よろしくお願いいたします。
>>452 CStringがそもそも一般的じゃありませんから。
残念、VCは専用スレへ斬り!
>>453−454
(つェ`)えーん
VC専用スレがみつからなかったんですよ。
【VC++】プログラム作成に手を貸して下さい!!
スレなんですかね?板汚しすまそんでした。。
他のスレは過疎ってそうなのでwebでも少し探してみます。ありがとうでした
>>456 ぎゃ・・・検索が甘すぎでした
PathRemoveFileSpec
お、こんな便利なAPIがあったんですね、これで試してみます。
ありがとうございました。
my_dick.insert(find(pussy.begin(), pussy.end(), boost::bind(younger_than, _1, 25)));
>>458 dick に pussy をいれるのか?
strncpy()関数の使い方の確認なのですが 下記の使い方で
うまくいく場合と行かない場合があります。
ファイルから1行読み込み、2桁の数字、5桁の数字、12桁の英数文字
を抜き取る作業なのですが関数の使い方は合っているでしょうか?
----------------------------------------
FILE *fp;
int a, b;
char str0[256];
char str1[256];
fp = fopen ("M:\\test\\data1.txt", "r");
if (fp == NULL) exit (-1);
while (fscanf (fp, "%s", str0) != EOF) {
strncpy (str1, str0, 2);
a = atoi (str1);
strncpy (str1, str0 + 3, 5);
b = atoi (str1);
strncpy (str1, str0 + 9, 12);
keisan1 (hwnd, a, b, str1);
}
fclose (fp);
---------------------------------------
データファイルの中身
01,23456,abc456ghijkl
52,63481,vwxyz.abcdef
:
:
>>460 strncpyは指定された文字数ちょうどをコピーしたときには文字列終端の'\0'を書き込まないため。
462 :
460:2005/07/25(月) 12:23:29
>>461 なるほど! どうもありがとうございました m(_ _)mぺこ
CSVファイルの読み込みにboost::tokenizer使うのは、やっぱりダメなんだろうか。
>>464 >>460のケースだと、固定幅フィールドファイルではなく、CSVファイルに見えたから。
であるなら、車輪の再開発はしなくてもいいのにと思った。
ただ、ソースコードはCコンパイラでコンパイルできるものなので、
C++は使えない環境なのかもしれないとも思った。
C++は使えても、boostは使えない環境なのかもしれないとも思った。
>>465 このスレではC++が使えない環境のことは考えなくていいんでは
boostは使えないかもしれないけど
boostが駄目でもstd::getlineがある。こいつに','を指定すれば……。
もちろんboost::tokenizerとは挙動がいろいろと違うけれどね。
マルチバイト文字の罠もあるね。
CSVは""の扱いとかウザい
素直にTSVつかっとけよ
470 :
デフォルトの名無しさん:2005/07/25(月) 19:52:55
>>469 毎回コーディングし直すからうざいんちゃうの?
MTじゃなさ気だし、strtok()使うのが吉。
strtok()使うくらいならsscanf()でいいじゃない。
473 :
デフォルトの名無しさん:2005/07/26(火) 04:59:30
野球におけるピッチャーの防御率は,9回あたりの失点数で計算します.
なので,低い程よくなります.そこで,1試合ごとの投球回数と失点数
を入力し,「全試合を通しての防御率」と「最近5試合の防御率」を入
力するたびに計算するプログラムを作ってください.ただし,1/3 回
のようなアウトカウントによる投球回数は考えず,投球回数単位で計算
するものとします.
下の表に出ている値で正しいかどうかを確認してください.
なお,最大140試合まで入力できるようにしてください.また,
日本のプロ野球では,延長戦は12回までなので,投球回数に12より
大きい数値は入らないようにしてください.
質問です。
クラスの継承で、アクセスコントロールをメンバ関数個別に設定する事は可能でしょうか?
たとえば、
class A{
...
public:
void Func1();
void Func2();
};
class B : public A{
...
};
の時、
「クラスAのオブジェクト → 外部からFunc1,Func2両方アクセスできる」
という条件を維持したままで、
「クラスBのオブジェクト → 外部からFunc1はアクセス可だが、Func2は不可」
のような設定を実現する方法はあるでしょうか。
476 :
475:2005/07/26(火) 07:45:43
すいません、自己解決しますた。
継承先のクラスでprivateで多重定義すればよかったですね。
>>476 class A {
public:
void Func1();
void Func2();
};
class B : public A {
void Func2();
};
こういうことならこうできるけどいい?
B obj;
obj.A::Func2();
private継承ということではなかろうか。
で、再定義するよりも、public部で公開したいものをusingする方が
メンテ上ベターでしょう。
479 :
475:2005/07/26(火) 11:15:22
>>477-478 回答ありがとうございました。
>private継承ということではなかろうか。
はい、そうです。
478さんの方法を試してみます。
勉強になります。
480 :
475:2005/07/26(火) 13:09:40
たびたびすいません。
private継承して継承先からはアクセス不可にしておきたい基底クラスのメンバはごく一部で、
継承先のpublic部でusingして公開しようとしているメンバの方が数が圧倒的に多いです。
そのため、今478さんの方法を試そうとしているのですが、
継承先のpublic部にかなりたくさんのusing記述をする事になってしまいそうです。
他に、継承先クラスから基底クラスの一部のメンバだけを個別にアクセス制限
できるような方法はないものでしょうか。
継承クラス関係で調べているのですがなかなかそういう方法がみつかりません。
>>480 無理かもしれんが、クラスがでかすぎるようなら
役割でクラスを分割して複数のオブジェクトにするといいかも
>>480 struct base
{
void a();
void b();
void c();
};
struct derived : base
{
private:
void c() { base::c(); }
}:
>>480 publicで継承して、見せたくない部分だけprivateでusingすればいいんじゃね?
>>480 >private継承して継承先からはアクセス不可にしておきたい基底クラスのメンバはごく一部で、
>継承先のpublic部でusingして公開しようとしているメンバの方が数が圧倒的に多いです。
を理由に
>>482 >publicで継承して、見せたくない部分だけprivateでusingすればいいんじゃね?
はあんまり良くないと思うよ
public継承ってことは
基底クラスの参照ポインタで普通にアクセスできてしまうからね
#include <iostream.h>
char *run()
{char *dp,d[]="running";
dp=d;
return dp;
}
void main()
{char *tp,t[10];
tp=t;
tp=run();
cout << tp << endl;
}
何分基本的な事で申し訳ありません
文字列を返す関数を作りたいのですが、上記のもの実行すると
running・↕ฺと、お呼びでないものも表示されてしまうのです
多分メモリが解放されている為だと思うのですが、何か良い方法は有りませんか?
> 何か良い方法は有りませんか?
{まず、中括弧をキモイ位置に配置するのはやめなさい。
}
const char* run() {
const char*dp="running";
return dp;
}
char *run(char*s){
char *dp="running";
return strcpy(s,dp);
}
>>485 >#include <iostream.h>
アナクロすぎ。
文字列を返す関数が欲しいだけなら
const char * run() {return "running";}
でいい。
コンストラクタが自動的に継承されない理由って何?
template使うときにこれが障害になることがかなり多いんだけど。
492 :
デフォルトの名無しさん:2005/07/26(火) 20:28:56
>>491 え? そういう必要があるときに template 使うよ??
質問です
for ( int a = 0, unsigned int b = 0; a < 10; a++, b++ ) {
}
これってなぜにダメなのでしょう?
初期値に宣言でおけるのは1つだけ?
おとなしく
unsigned int b = 0;
for ( int a = 0; a < 10; a++, b++ ) {
}
としておけということ?
495 :
デフォルトの名無しさん:2005/07/26(火) 20:33:43
>>493 unsigned は予約語なので変数名になれない
コンパイラは心を持たない
496 :
493:2005/07/26(火) 20:34:18
>初期値に宣言でおけるのは1つだけ?
ちと言葉足らずでしたが
for内だけのスコープを持つ変数宣言は1つしかできないのか?
という意味です
for ( a = 0, b = 0; a < 10; a++, b++ )
ができるのはわかっています。
497 :
493:2005/07/26(火) 20:34:54
あら、1つだったのね・・
いくつでもできる気がしてた・・
498 :
デフォルトの名無しさん:2005/07/26(火) 20:36:43
>>493 俺んとこではダメだったけど、これなら通ってもよさそうな気がする
for ( (int a = 0), (unsigned int b = 0); a < 10; a++, b++ ) {
}
500 :
デフォルトの名無しさん:2005/07/26(火) 20:38:32
>>500 規格の文法上不可能だから。
ISO/IEC 14882:1998 Annex A Grammar summaryより
for ( for-init-statement condition(opt) ; expression(opt) ) statement
for-init-statement:
expression-statement
simple-declaration
expression-statement:
expression(opt) ;
simple-declaration:
decl-specifier-seq(opt) init-declarator-list(opt) ;
decl-specifier-seq:
decl-specifier-seq(opt) decl-specifier
decl-specifier:
storage-class-specifier
type-specifier
function-specifier
friend
typedef
init-declarator-list:
init-declarator
init-declarator-list , init-declarator
init-declarator:
declarator initializer(opt)
502 :
493:2005/07/26(火) 21:04:07
for ( a = 0, b = 0; a < 10; a++, b++ )
↑はgcc拡張だったぽ・・
通常規約上だめなのかも・・ちなみにVCだめ
gccばっかつかってたためか標準でおkかとおもてた
orz
503 :
デフォルトの名無しさん:2005/07/26(火) 21:04:49
>>501 オブジェクトの定義を囲う括弧が実行文でなくなる制限についての関連事項はどこだ?
関数の名前のつけかたなのですが
namespace
で細かい分類をするのって薦められるやりかたなのでしょうか?
こんな感じです
MyLib::SubsDataA::sub1(){ .. }
MyLib::SubsDataB::sub1(){ .. }
MyLib::SubsDataC::sub1(){ .. }
>503
それを>501はそのまんま書いているわけなんだけど……。
もしかして規格書の文法記述読めない?
>>503 for-init-statementの内のsimple-declarationでは無理として(見ての通り)、
expression-statementの方のことを言っているのなら、expression-statementの
文法を実際に見てみれば、expression-statementの中ではオブジェクトの定義が
出来ないことは分かる。
507 :
501:2005/07/26(火) 21:24:28
>>503 for-init-statementの内のsimple-declarationでは無理として(見ての通り)、
expression-statementの方のことを言っているのなら、expression-statementの
文法を実際に見てみれば、expression-statementの中ではオブジェクトの定義が
出来ないことは分かる。
508 :
501:2005/07/26(火) 21:27:55
>>503 for-init-statementの内のsimple-declarationでは無理として(見ての通り)、
expression-statementの方のことを言っているのなら、expression-statementの
文法を実際に見てみれば、expression-statementの中ではオブジェクトの定義が
出来ないことは分かる。
509 :
501:2005/07/26(火) 21:30:02
>>503 for-init-statementの内のsimple-declarationでは無理として(見ての通り)、
expression-statementの方のことを言っているのなら、expression-statementの
文法を実際に見てみれば、expression-statementの中ではオブジェクトの定義が
出来ないことは分かる。
読めないから503みたいな事書いたんだろうね
>>502 VCとCWで拡張なしで普通に通ったよ?
int main()
{
int a, b;
for (a = 0, b = 0; a < 10; a++, b++){}
}
512 :
デフォルトの名無しさん:2005/07/26(火) 21:42:32
読めないなら素直にそう言えよ……
514 :
デフォルトの名無しさん:2005/07/26(火) 21:58:45
515 :
デフォルトの名無しさん:2005/07/26(火) 22:04:37
自分の発言の読者の知識をどのように想定しているんだ?
>>511 カンマ演算子自体はC時代から普通に使えるよな
517 :
501:2005/07/26(火) 22:12:36
人大杉だったのか…多重書き込みスマソ
>511
それ(a=0, b=0)は宣言ではなくてexpressionだから。
えー、pc8鯖が強烈に重いので、多重注意しておくれ。
>515
C++相談室で回答者やる程度にはC++と規格書の読み方に関する知識がある人間じゃない?
520 :
511:2005/07/26(火) 22:34:36
521 :
511:2005/07/26(火) 23:03:00
なんで書き込めないんだ
ある程度復活したようで。
524 :
デフォルトの名無しさん:2005/07/27(水) 02:53:19
"C++はメモリがいくら使われるか分かる"らしいんですけど,
必要なメモリ量=実行ファイルの大きさ
で合ってます??くだらない質問ですいません。
とりあえずここは合ってる
>くだらない質問
527 :
デフォルトの名無しさん:2005/07/27(水) 03:24:44
>>524 むしろCの方がどのくらいメモリを使うかは分かりやすいかと。
あまりそういう細かいことを知らなくても人の作った部品をうまく
組み合わせて全体を作るためのオブジェクト指向でもあるわけだし。
構造体のメンバにstd::vectorを入れることは出来ますか?
こういう感じの。
struct A
{
int x;
int y;
std::vector<int> vect;
};
>>529 まずやってみて、問題があったなら問題点を相談しろ。
コンパイルできるかならできる
memcpyとかでは使えない
可変データを扱う場合はclassを使うべき
コピーコンストラクタを持たせるべき
現実的には、C++の構造体=デフォルトのアクセス制限がpublicなclassだから、
structの中にstd::vectorを入れることはできるし、std::vectorを使うことが直接的な問題は引き起こさない。
ただし、セオリーとして、std::vectorを使うときはコンストラクタでだいたいの大きさを指定する:
A() : vect(1000) {} // A::vectはほとんどのケースで1000程度の要素数を持つと予想されるとき
これはパフォーマンスのためと、そのクラスがどの程度のデータを扱うことを想定しているかのヒントのため。
>>534 コピーコンストラクタは、ポインタをメンバに持つときに定義するべきでは?
std::vectorなら、コンパイラが暗黙に定義するコピーコンストラクタで問題ないはず。
537 :
デフォルトの名無しさん:2005/07/27(水) 06:38:37
std::vectorのようにコンストラクタを持つデータを構造体の中に入れちゃったら
それはクラスになっちゃうのでクラスの性質がよくわからない人はやっちゃダメです。
クラスになると言うより、PODでなくなると言う方が適切だと思う。
>>536 ん? そういうヒントのためにはvector::reserveを使うべきでは?
いや、最初から1000の要素が必要ならそれでも良いけど。
>>534 そんなルールはありません。
>>536 そんなセオリーもありません。プログラムの都合にあわせて好きにすればいいはずです。
>>538 C++での「クラス」と「構造体」に性質の違いはありません。
542 :
デフォルトの名無しさん:2005/07/27(水) 11:19:09
もううんざりするほどバカが多いね。
なにこの板。
C++での「クラス」と「構造体」の違いなのか、他のなんというかワカラン概念での「クラス」と「構造体」なのか
そこがハッキリしてないな。
>>543 それぐらい知ってますよ
C++でいう構造体とクラスは本質的には同じ物で、何も書かなかった時にデフォルトでpublicかprivateになるという違いがあるだけでしょう?
>>544 じゃあ何が聞きたいんだよ
人間初心者はお断りだぞ
コピーコンストラクタとoperator=は必ず書く。
これでモーマンコタイ
>>544 漏れが危惧したのは、質問者がいう「構造体」とは何かということだった。
ふつうC++プログラマであれば、structとclassに本質的な違いを設けないし、
それゆえstructであっても「クラス」と表現すると思ったからだ(妄想かもシレンが)。
ここはC++スレだが、明らかにC言語の質問も結構書き込まれるからな。
std::vectorをメンバに持たせたとき、「C言語の構造体」にできるすべての操作が保証されるか?
という質問に見えた。
おそらくそれで他の回答者もmemcpyが使えない(PODでないため)とか、
クラスの性質を知っておけとかのレスをつけたんだろう。
>>548 だから、
コピーコンストラクタとoperator=は必ず書く。
これでモーマンコタイ
特に必要が無ければ書かないなあ。デフォで各メンバのoperator=が呼ばれるし。
普段書いとくと
書き忘れがなくなるっしょ。
>>552 書いておけば書き忘れはなくなるだろうけど、中身が正しい保証は無いよね。
メンバを増やしたときにそのコピーを忘れるとかしないのかなぁ。
554 :
デフォルトの名無しさん:2005/07/27(水) 15:25:41
現在大学でC言語を一通り取得した学生です。
現在の状況としては。
簡単な住所録アプリケーション
1、検索、データの追加、削除、修正。
2、単純選択法によるソート機能(降順、昇順)
3、UNIX(Soralis)環境での、カレントディレクトリの
datファイルの表示、印刷機能
を実装したものを作れるような状態です。
この後、Windows環境でのC++を勉強していきたいと思っているのですが
どのような参考書を選ぶべきか迷っています。
どなたか、参考に教えていただけないでしょうか?
>>553 確かに
「寿命管理しなきゃいけないポインタがあるのにコピーコンストラクタを書き忘れる」
という大きなポカをするような人なら、
「メンバを1つコピーし忘れる」
なんていうマイナーなポカはその10倍くらいやってもおかしくないな・・・
557 :
デフォルトの名無しさん:2005/07/27(水) 15:35:17
>>555 C++に関する質問のスレだったので
こういった、質問をしてもいいのか
と思ったのですが、スミマセン
558 :
デフォルトの名無しさん:2005/07/27(水) 16:10:41
ファイルサイズをバイト単位で取得するにはどうしたらいいでしょうか?
559 :
デフォルトの名無しさん:2005/07/27(水) 16:28:34
>>558 BYTE getFileSize(UNKNOWN_SIZE file_size)
{
return static_cast<BYTE>(file_size);
}
>>558 たぶんseekg()で末尾に移動してtellg()
istreamの場合。
>>554 まずCとC++は別言語。次にWindows環境でのフレームワークによって参考書は違う。
まず、Windows環境で、どんなプログラミングスタイルを取るか考えろ。
そして開発環境についての質問は他のスレッドへ。(ここで扱うのは標準C++であってVC++でもgccでもない)
>>558 inline size_t filesize(ifstream& fin)
{
size_t current = fin.tellg();
fin.seekg(0, ios::end);
size_t size = fin.tellg();
fin.seekg(current);
return size;
};
そこはg++って言ってやれよ
>>558 テキストモードだと
seek()、tell()ではだめ
つか、素直にstat()使っとけ
標準じゃないけど、使えるだろ
564 :
デフォルトの名無しさん:2005/07/27(水) 19:58:37
「ファイルサイズ」を求めるのに、どうして EOT 等を検索する必要があるんだ?
2GBを超えるファイルサイズを取得するできうる限り汎用的な方法は?
wxWidgets
567 :
デフォルトの名無しさん:2005/07/27(水) 20:09:44
EOT まで 1byte ずつ数えても、それが「ファイルサイズ」である保証は?
使ったことはないけどBoost::Filesystem
>>568 boost::intmax_tは64bitとは限らないんじゃないか
>>564 ファイルサイズを直接求める関数は標準ライブラリに用意されていない。
>>567 全くない。戻り値はpos_typeでしかない。
571 :
デフォルトの名無しさん:2005/07/27(水) 20:39:42
>>565 size_tが2GB超に対応していれば561の方法。
size_tはunsigned 32bit整数という環境が多いんじゃないかな
574 :
デフォルトの名無しさん:2005/07/27(水) 22:46:04
今、ファイル分割結合のソフトを作っているのですが、
バイナリデータでファイル読み込みして一度それをChar型に格納するにあたり、
わりと大きなサイズのファイルでも格納できるようには動的にとればいいのですか?
意味あるんでしょうか?
初心者で申し訳ないっす。
>>574 うむ。
動的にとるほうが、一度に確保できるサイズは大きい。
576 :
デフォルトの名無しさん:2005/07/27(水) 22:53:18
上の574は558でファイルサイズの取得関数を聞いていたものですが、
あの後、調べててfileno(*fp)とfilelength(long *)と<io.h>のインクルードで
出来ました。間違ってました?
>>576 できたならそれでいいじゃないか。
ただし、そいつは非標準なのでこのスレの範囲外。
578 :
デフォルトの名無しさん:2005/07/27(水) 22:56:23
>>575 やはりそうですか。
動的なとりかたとしては、
#include<stdlib.h>で
char *data=(char *)malloc)(sizeof(char)*1000000
とかでよろしいのですか?
もっといい方法あります?
>>578 new char[1000000]とかあるいはstd::vector<char>の方が一般的だと思う。
windowsならば「動的にとるから大きな領域取れる」というよりも、
「ヒープにとるから大きな領域取れる」が正しいのでは?
581 :
デフォルトの名無しさん:2005/07/27(水) 23:02:57
>>579 あっnewって聞いたことあります!なるほど!
それもfreeでメモリ開放は必要ですか?
582 :
581:2005/07/27(水) 23:04:56
そんなの自分で調べろって感じですよね。。。失礼しました〜
583 :
デフォルトの名無しさん:2005/07/27(水) 23:05:05
freeじゃなくてdeleteです
deleteではなくdelete[]です
>>574 静的に取って味噌。キーワードはstatic。
586 :
574:2005/07/27(水) 23:21:39
>>585 えっ静的にとったらどんなファイルサイズでも対応できるようには
ならなくないすか?
でも味噌ってことは、静的にとるメリットがあるってことか
>>586 > えっ静的にとったらどんなファイルサイズでも対応できるようには
> ならなくないすか?
大きな領域を取りたいと書いてあった(
>>574)からそう書いた。
ホントに動的にとりたいのなら、動的にとるしかないではないか。
>>586 動的にメモリを確保したところでどんなファイルサイズでも対応(一括で収まるって意味?)できるようになるとは限らない。
>>581 std::vectorならその手間も要らない。
ファイルの分割結合なら、ほんとはいちいちバッファに入れる必要も無いけどな。
やるんなら
>>585のとおり、staticである程度確保しておいて、一気に読み込む方法だろうな。
大先生がいっぱい居る様だから、俺が口挟むことじゃないけど
NEWとMALLOCの違いって知ってるかい?
メンバ変数だけ捕獲させるなら麻呂でいいけど、メンバ関数捕獲するなら、要は、捕獲したメモリにクラス入れるとして、そのクラスに::が
あったらNEW使わないと・・・、中でどうなるかは知らない・・・、どうなるの?
それから、「動的」確保の罠って知ってる?
動的に確保して、ポインタにポインタを突っ込むとどうなるか?w
長いコードだときっとやらかす、目立wたないところできっとマラカス、でデスマらかすw
STATIC?それは性的メモリ確保っていうか、初期化のタイミングの違いってだけの認識で、単なる変数定義だと思うけど?
593 :
デフォルトの名無しさん:2005/07/28(木) 01:34:39
静的確保はGlobalAlloc,Globallockのセットでしょ、安定的に・・・
でかいブツなら仮想メモリも使いやすいしね
>>593 標準にGlobalAlloc,Globallockなんて無い
ADLを嫌って修飾名で関数を呼ぶことがあると思いますが
無名名前空間内の関数はどう修飾するのがベストでしょうか?
>>595 その台詞は、592が死にそうなシチュエーションですね
無名名前空間内って何?
::のことか?
プププ
アホばっかだな
検索したらすぐわかったわ。
せっかく勝ち誇ってたのにすまんね。
検索する前に知っていようぜ……。
>>593 でかいでかいというのだからVirtualAllocだろ。
ちょこっとだけでWin32ならHeapAlloc。
GlobalAllocはクリップボードなど特殊用途。
すれ違いスマソ
>>574 UN*Xならmmap()
WindowsならCreateFileMapping & MapViewOfFile()
607 :
606:2005/07/28(木) 13:44:24
うほ、スレ間違えた(汗)
64bitプログラミングに書いたつもりだった
クラス内でusingするってどういうこと?
>>608 class B
{
public:
void f();
void g();
};
class D : private B
{
public:
using B::f;
};
D obj;
obj.f(); //OK
obj.g(); //NG
こういう風に継承時のアクセス制御を書き換えたいときに。
クラスB, Dを次のように定義
struct B {
template <class T> void f(const T& t) { cout << "T" << endl; }
virtual void f(const B& b) { cout << "B" << endl; }
};
struct D : public B {};
ここで、
B b; D d1, d2;
とすると、
d1.f(0); // (int)0 -> templateの方が選択される
d1.f(b); // B -> f(B)の方が選択される
d1.f(d2); // D -> templateの方が選択される
となります。ここで、
d1.f(static_cast<B>(d2)); // B -> f(B)の方が選択される
のように明示的にキャストせず、派生クラスの場合には
d1.f(d2);だけでf(B)が選択されるようにするには
どうすればいいですか?
>>610 struct D : public B {
void f(D const& d) { B::f(static_cast<B>(d)); }
};
キャストは参照にした方がいいよ
574じゃないけどちょっと気になって
static char a[500000];をつけてコンパイルしてみた。
予想と違った。実行ファイルのサイズは変化無し。
static char a[500000]={"a"};と初期化してみた。
予想どおり500kバイト増えた(と思われる)。
>>613 staticな配列の中身がゼロでも、実行時に初期化する処理系と、あらかじめDATA
として持っておき、転送する処理系がある。コンパイルオプションで切り替えられる物
もある。
test
617 :
デフォルトの名無しさん:2005/07/29(金) 06:52:35
templateクラスでstatic変数を扱いたいのですが可能でしょうか
もし可能ならば、.cppファイルの方でそのstatic変数を確保する際の、記述方法を教えて頂けないでしょうか
618 :
617:2005/07/29(金) 07:00:50
class Aの内部でさらにclass Bを定義した場合
Aのメンバー変数にBからアクセスできません。
どうすればアクセスできますでしょうか?
class A{
int m_value;
class B{ void do(){std::cout << m_value } }
};
error C2327: m_value : 型名、スタティック、または列挙子ではありません。
といわれます
>>619 それはA内部でBを宣言したと言うだけなので、AのインスタンスとBのインスタンスには何の関連もない。
アクセスするためにはAのインスタンスへの参照をBに渡すか、適切なI/Fを設けることになる。
>619
よーく考えてみろ。
B hoge;
hoge.do();
なんてコード書かれたらどうする気だ?
どこにm_valueがあるのかと小一時間(ry
nested classは非直感的という気はするけどな。Cつかってた人には常識なのかもしれんけど。
B hoge;は無効になり、Bのインスタンスの生成やアクセスはAにしかできず(private扱い)、
かつ内側のクラスは外側のクラスのメンバにアクセスできるというのがよかった。
コンパイラがAのインスタンスへの参照を暗黙で書いてくれればいいのに。
(virtualみたいなキーワードで書いてくれるようになる、でもいい)
この考えはやはり変なんだろうな
俺は単にそのクラスの中でしか使わないクラス、という意味でよく使うから勝手に外のクラスへの参照を持たれると困るな。
C++.netでテキストファイルを出力する際に、自動的にナンバリングするようにしたい
のですが、どのように行えばよろしいでしょうか。
イメージとしては、出力ファイルが
hoge1.txt
hoge2.txt
hoge3.txt
:
:
といった感じです。どうかよろしくお願いします。
>>625 まず自分でやってみてから、わからないところを相談しろ。
std::string get_filename(std::string prefix, int n, std::string suffix)
{
std::stringstream ss;
ss << prefix << n << suffix;
return ss.str();
}
int i = 1;
while (first != last) {
std::ofstream fout(get_filename("hoge", i, ".txt").c_str());
//
fout.close();
++i;
}
または
sprintf("hoge%d.txt", i);
桁数を揃えたければ%0?dなりsetfill('0') << setw(?)なりすればよい。
>>625 自動でナンバリングなら専用のクラス作ればいいだろ
こういったアルゴリズム以前のプログラミング感覚みたいなもんはどこに回したらいいのやら。
ああ、自動でナンバリングって、引数にカウンタ指定するとかじゃだめなんだ。
それだと
>>627はダメだな。
privateメンバにカウンタを持たせて、ファイルに出力するときにそのカウンタ使ったら?
いや、既に存在するhoge[0-9]+\.txtのファイルを調べて、
最大の番号+1のファイル名を求めたいということかもしれんぞw
boost::filesystemでも使え。そうすれば少しでも環境依存性は抑えられる。
>>634 MBCSのパスにもワイド文字のパスにも対応してないから、日本語絶望的。
pointer = NULL
は値がはいっていないことをはっきりさせるために
使うのが本来の使い方でしょうか?
>>637 ポインターをどうしても生で使いたいのならそうでしょう。
「入ってない」というか、「有効でない」ですが。
あるデータdataOrgを変換したデータdataConverted
が必要になったときだけ計算するようにしたい。
class Cdata{
public
DataClass dataOrg;
DataClassConverted *pdataConverted;
void callConverted();
};
dataConvertedのコンストラクターがcallConverted()を最初に呼ばれたときのみ実行されて
2回目からはpdataConvertedのメンバー変数(最初に呼ばれたときに計算された結果)が帰ってくるようにしたい。
DataClassConvertedをどう設計すればいいんだろう.
640 :
606:2005/08/01(月) 14:09:43
>>639 その日本語の説明そのまま実装すればいいんでないの?
void/*voidで何を返すんだ*/ Cdata::callConverted() {
if (this->pdataConverted == NULL)
this->pdataConverted = new DataClassConverted(this->dataOrg);
return this->pdataConverted->メンバー変数;
}
641 :
639:2005/08/01(月) 15:04:03
>>640 やっぱりNULLはそういう意味で使うんだ
pdataConvertedの初期化を忘れずにね。
>>641 CDataクラス内にbDataConvertedみたいな初期化フラグを付けるって手もあるけどね
この場合はポインタを直接見た方がスマートかな
state patternって手もあるけどな
・callConvertedを面罵関数ポインタにして、初期状態で指す先の関数は
変換処理を行ってcallConvertedを次の関数に書き換え、変換済みデータを返す。
・次の関数は変換済みデータを返すだけ。
>>637 C++ではNULLよりも0推奨。
NULLを(void *)0にできなくなったから、
オーバーロード解決時に思わぬことが起こりえる。
Linux環境で、C++を使ったwaveファイル編集ソフトを作る予定なのですが
何かオススメの参考書はありませんか?
録音済みのwaveファイルを取り込んでから
・ノイズ除去
・再生速度の変更(低速再生)
・ボリューム調節
などを行い、再度waveとして出力する予定です。
>>646 二重三重にスレ違い。
ここは環境依存スレではないし書籍スレでもない。
処で、waveファイルって何のこと?
もしかして:.wav
自信たっぷりな647の3、4行目で、こっちが赤面したくなったわい
649 :
646:2005/08/02(火) 15:20:55
そうですね。スレ違い申し訳ありません。
適当に他のスレで聞いてみたいと思います。
あと、waveファイル云々はどのように解釈すればよいのですか?
間違ったことは申し上げていない と思っているのですが・・・
>649
>647が痛々しいだけだから無視していいと思うよ。
「waveファイル」で検索すると、概ねWindowsAudioFormatのことのようだ。
しかし、それをwaveファイルというのは正しそうで正しくないのかも知れず。
かと言って、それを論うのはスレ違いなことこの上ないので続けたいなら他所へ行け。
>>647がどう思ってこれを書いたのか、興味があるので
説明して欲しいんだが、出てきてはくれんかな?
恥かいちゃったんでもう出てこれないか…
作りたいだけなら、書籍よりwebでサーチした方がいいよ。
というのも、書籍だとまず数学的準備から始まって、数学的証明で終わる。
その中に時々本当にやりたいことについて説明した数式が入ってる。
基礎を押さえて勉強したいとか、信号処理の研究をしたいとかならいざしらず
単にプログラムが書ければよければ信号処理 fft wavelet等でgoogleおすすめ
C言語からC++に乗り換えようと思って
独習C++って本を買おうと思ってます。
C言語については
基礎的な事はある程度できると思いますが
使いこなせていない状況です。
こんなヘッポコレベルの私でも独習C++を理解することができて
また、C++を使いこなすことができますか?
うん
わかりました
早速アメゾネで注文してきます。
運の間違いじゃないか?
>>658さんの発言で迷いました。
どなたか 最後の決断をたのみます。
660 :
デフォルトの名無しさん:2005/08/02(火) 20:47:13
647 晒しage
何がしたいかにも寄るけど・・・
Cが「使いこなせてない」と感じる理由が、最近のソフトやフレームワークが
C++ で書かれていることが多いから、ということなら C++ に移行する意味はある。
そうではなく、C で書かれた様々なもののソースを観てもピンとこないというのなら、
C++ に移行したところで何がどうなるとも思えないので VB や C# や Mathmatica
や perl など適当に優しげなものに移行すべきかと思う。
>>661さん
とてもよい、アドヴァイスありがとうございます。
私はゲームプログラマーを志望しているのですが
ゲームについてのアルゴリズムを
ゲームのアルゴリズムについて書かれている本やウェブサイトで学んでいます。
私C++に移行したいと思った理由は
C++を元に解説をしている書物などがあるからです。
というわけで アマゾネで注文することを決めました。
どちらの国の方ですか?
664 :
デフォルトの名無しさん:2005/08/02(火) 21:13:16
特定ロケールに依存するなタコ
ごめんなさい、私は言葉が不自由な人間なので
翻訳ソフトで翻訳されたような 日本語でしたね
日本人なので、安心してください
>>663さん
>>646 sox
audacity
ソフトだとこのあたりが参考になると思う
>>663 日本人だからと言って日本語が話せるとは限らない。
結局>646に関しては、
音声データだと思っている香具師と、
波形データと思っている香具師と、
意図的に混乱させている香具師と、
その他の悪乗りがレスしているものの
本人が出てこないもんだから決着つかない罠。
わざわざ難しく解釈して悦に入っている香具師が一人いるだけの希ガス
悦にっていうか、このままじゃ自分だけが馬鹿ってことで決着しちゃうから、
何とか「真相は闇の中」的オチに持っていこうとしてるんでしょう。彼が。
結局、音声データファイルをWAVEファイルと言ってたって落ちでよさそうですが。
671=647?
673 :
639:2005/08/03(水) 14:51:14
結局こんな風にした。CGiveValueMethodFunctorはFunctorでなくて関数ポインターにしたかったけど、なぜかコンストラクターが関数ポインターを受け取らないのでFunctorにした
template <class CValue,class CGiveValueMethodFunctor>
class CValueWithGivenFlag
{
public:
bool given;
CValue value_;
CGiveValueMethodFunctor giveMethod_;
CValueWithGivenFlag(CGiveValueMethodFunctor &giveMethod):giveMethod_(giveMethod), given(false){}
CValueWithGivenFlag(CValue &valueInput, CGiveValueMethodFunctor &giveMethod): giveMethod_(giveMethod), given(true), value_(valueInput){}
CValue & value(){
if(given){
return value_;
}else{
giveMethod_(value_, given);
return value_;
}
}
void putValue(CValue &v)
{
given=true;
value_=v;
}
};
struct B { int member; };
std::ostream& operator<< (std::ostream& os, const B& b) { return os << b.member; }
これで、
B b; std::cout << b << std::endl;
が通る。
このベースクラスBを派生すると
struct D : public B {};
D d; std::cout << d << std::endl; // エラー
コンパイルできない。
ベースクラス用のoperator<<()を呼び出すような実装をするとき、
std::ostream& operator<< (std::ostream& os, const D& d) { この部分; }
に何を書けばいいのか教えてください。
>>674 std::ostream& operator<< (std::ostream& os, const D& d){ return os << static_cast <const B&> (d); }
>>674 つ〜か、VC7.1ならそのままで普通に通るんだが。
>>675 そう書いててダメだったのでわからなかったんですが
すげースンマセン! クラス設計変えて、継承をやめてました!
どおりでinvalid static_castエラーのはずだわー
うへえー(´д`;)
678 :
675:2005/08/03(水) 18:03:28
誰も聞いてないと思うが、その継承をやめたクラスはダライアスでいうとステージHあたりです。
多重継承はまぞくておもしろいです。
ダライアス継承?
あれはマゾどころか魔窟だ。
681 :
デフォルトの名無しさん:2005/08/03(水) 20:13:01
クジラとタツノコを多重継承したやつと戦ってみたい
>>673 なんでそんなことに?
>640のほうがはるかにマシに見えるんだが。
そういや、ダライアス継承実装したサンプルってどこかにある?
>>683 そんなにしてほしいのか?
struct A { A() {} virtual ~A() {} };
struct B : public A { B() {} virtual ~B() {} };
struct C : public A { C() {} virtual ~C() {} };
struct D : public B { D() {} virtual ~D() {} };
struct E : public B, public C { E() {} virtual ~E() {} };
struct F : public C { F() {} virtual ~F() {} };
struct G : public D, public E { G() {} virtual ~G() {} };
struct H : public E, public F { H() {} virtual ~H() {} };
struct I : public G, public H { I() {} virtual ~I() {} };
動くかどうか検証はしていない。ご利用は計画的に。
>>684 ダライアス継承は仮想継承にしてなんぼだろうが。
687 :
デフォルトの名無しさん:2005/08/04(木) 19:49:35
>>684 A::~A() が virtual になっているなら空の B::~B() を手動で定義しなくてよい
>>687 そうなのか?てっきり全部ばらばらの働きをするデストラクタも含めて継承して
この例だとIか、あの最後の奴を継承したときどうなるかってことだと思ってたんだが。
685とあわせて全然修行不足だな。すまん。
689 :
デフォルトの名無しさん :2005/08/04(木) 22:56:17
動的に確保して値を代入した5次元の配列2つをあるクラスに渡すには
どうすれば?
int a[s][t][u][v][w]
int b[s][t][u][v][w]
という配列に値は入っています。
クラス (ここをどうするか)
{コンストラクタで代入はできますか}
690 :
デフォルトの名無しさん:2005/08/04(木) 23:02:19
unko::unko((int (*manko)[s][t][u][v])) : chinko(manko) { }
691 :
デフォルトの名無しさん:2005/08/04(木) 23:20:30
TEST::TEST(int (*kontena)[s][t][u][v])) :kontena2( kontena)
{
}
よくわかりません。解説お願いします。
これでa,b2つの配列ともクラスに渡せて、そのクラスの中で配列に入っている値を得ることが
できますか?
TEST::TEST(int 何か,int 何か){}のようなものを予想していました。
693 :
デフォルトの名無しさん:2005/08/04(木) 23:25:25
TEST::TEST(int a1[][t][u][v][w],int a2[][t][u][v][w])
{}
こういうことでしょうか?
694 :
デフォルトの名無しさん:2005/08/04(木) 23:28:12
ありゃりゃ、括弧が2重になってるやん
あーあ俺もいいかげん焼き回ったな
696 :
デフォルトの名無しさん:2005/08/04(木) 23:32:03
だめみたいです。
内部で新たに5次元配列を宣言して渡すという形にしたほうがいい?
動的配列だからその方法もわかりません。
698 :
デフォルトの名無しさん:2005/08/04(木) 23:43:19
配列が渡ってないようです。
TEST::TEST(int a1[][t][u][v][w],int a2[][t][u][v][w])
{ここになにか}
そりゃ入れないとだめですね。
3次元動的配列をクラスに渡す場合はどうやるのでしょうか?それを応用して考えてみようを思います。
配列の渡しわからねーー。
n次元動的配列って(1次元になるまで多重に)ループで
ひとつ低い次元の配列を要素サイズ分確保してループで埋めて作るやつかね?
そんなの自動で渡る方法なんかないっしょ。
クラス作ってコピーコンストラクタも提供でもせんと
700 :
デフォルトの名無しさん:2005/08/04(木) 23:51:08
>>699 そうです。自動で渡る方法ないんですか?
動的に確保したんだろ?
TEST::TEST(int***** a1,int***** a2)
これじゃまずいか
702 :
デフォルトの名無しさん:2005/08/05(金) 00:14:33
その方法わかるんやけど、どうやって配列の値を受け取るかわかる?
こんな風にクラスのある内部関数で
int temp =a1[2][2][4][5][7];
TEST::TEST(int***** a1,int***** a2,int s, int t, int u, int v, int w)
妥協
つかvector使えば?
>>689 コンストラクタで組み込み配列型メンバの初期化は制御できない。全部デフォルトの初期化になる。
つまり無理。
>>691 配列を渡したいのか、配列へのポインタを渡すだけで良いのかによって変わる。
2次元で考えると:
class X {
int **_x, **_y;
public:
X(int **x, int **y) : _x(x), _y(y) {}
};
自分なら、配列や配列へのポインタは扱わず、多次元配列のクラスを使う。
既存品ならBoost.Multiarrayかな。
でも5次元に特化した配列クラスなら1時間もあれば書けるでしょ。
そのクラスのインスタンスを、受け取りたい関数に渡す。
void f(CMultiArray *X, CMultiArray *Y) {}
CMultiArray *A = new CMultiArray(s, t, u, v, w);
CMultiArray *B = new CMultiArray(s, t, u, v, w);
f(A, B);
または、その5次元配列がなんらかの処理とセットで使われるなら、
それらをまとめてひとつのクラスにする。
ハッキリ言って5次元配列とかnewのループまわして作るのめんどいので
配列自体をカプセル化した方が良いよ。
コンストラクタ初期化子で
基底クラスの初期化の前に
派生クラスのオブジェクトを初期化することはできないのでしょうか?
無理。設計を見直しましょう。
710 :
707:2005/08/05(金) 11:19:39
>>708,709
ありがとうございます。
先に派生クラスのメンバを持つクラスを継承しておけば初期化できるんですね。
>>707 そもそも、派生クラスのオブジェクトに依存する基底クラスって設計がおかしい気がするのだが……
doxygenより楽にドキュメント作る方法ないんでしょうか?
Visual Studioに便利がツールが添付されてたりとか・・・
class Base {
Base(){
((Ext*)this)->init();
this->i = 0;
}
};
class Ext {
init();
};
これでひとつ。
714 :
デフォルトの名無しさん:2005/08/05(金) 17:05:24
>>712 VBCommenter 参考にしてプラグインを”自作”。
ただし C++ 用の CodeDOM は実装されていないので、
気合でパーサ書いて、実装しないとダメかも。
715 :
デフォルトの名無しさん:2005/08/06(土) 00:52:20
C++でsetjmp(),longjmp()を使ったら例外処理とか
まともに動く保証は無い?
18.7.4 の意味を正確に掴め兼ねるが多分、意訳すると
「catch 句の中へ飛ぶような使い方はするなボケ」で、
それ以外は規格的には大丈夫っぽい。
解釈が間違ってたら誰かふぉろーよろしく。
まぁ、基本的にはC++でsetjmp/longjmp使うぐらいなら例外で処理しとけ。
>>715-716 同じ流れを例外で行えばデストラクタが呼ばれるとき、longjmpを行うと未定義と書いてある。
JIS X3014 18.7
>>718 あー、"解体"ってのがデストラクタのことか。
俺も JIS X3014 を見てたんだけど、
ISO/IEC 14882 のほうがやっぱり読みやすいね。
720 :
デフォルトの名無しさん:2005/08/06(土) 15:37:27
随伴って何のことかと思ったよ
外部ファイルから読み取った値で,クラスのstatic const メンバー変数を初期化したいのです。
たくさんの(50くらいの)メンバーをこの方法で初期化するため,ファイルを読み込むクラスも作りました。⇒LoadFile
この方法ではうまく初期化できなかったので,別の方針をお尋ねしたいのですが…。
一度mapに全部ファイルの内容を流し込んでしまう方法も考えましたが,流し込む時点ではメンバーの型が
分からないので困っています。(外部ファイルに例えば「L=3」と書いてあっても,mapに追加する時点では
int, double, charのどれに利用するのか分からない)
#include <iostream>
#include "LoadFile.h"
using namespace std;
class Hoge {
static const int L;
static const double X;
public:
int getL() const { return L; }
double getM() const { return X; }
};
LoadFile fl("test.dat"); //ファイル名を渡すとそこから読み込んでくれるようにしました
/*fl.func();*/ //メソッドはいじれない
const int Hoge::L = 2;
/*const int Hoge::M = fl.getDouble("X");*/ //メソッドはいじれない
int main() {
Hoge hoge;
cout << hoge.getL() << endl;
/* cout << hoge.getX() << endl;*/
return 0;
}
実行時に動的に初期化することはできません。
>>721 なんで static const になってんの?
Hoge のインターフェースを見ると、メンバに LoadFile 持てばいいだけに見えるけど。
724 :
デフォルトの名無しさん:2005/08/06(土) 17:09:01
class について質問です。
class A {.....};
int main() { A a[20160]; }
とするとエラーが出ます。
自分で定義したクラスの配列には、制限があるのでしょうか。お願いします。
>>724 エラーが出るならエラーメッセージ貼れ。
デフォルトコンストラクタがないと予想
727 :
724:2005/08/06(土) 17:16:30
SIGSEGV です。メモリのアクセス違反でしょうか。
取りあえずコンストラクタ作ってみます。リアルタイムでサンクス。
int main(){
char c[4ギガ]
}
class A のサイズ576ですた(泣。
730 :
721:2005/08/06(土) 17:43:17
お二方,どうもありがとうございます。
>>722 そうですか…orz
>>723 staticなのは,Hogeのオブジェクト(複数)間で共通の定数だからですが,
定数なのでconstをつけようとして,おかしくなってきました。
もともとメンバーにLoadFileがあったので,staticだけにする方向で行きます。
他の関数からは見えないけどサブルーチンからだけは見える変数って作れる?
関数{
変数宣言
サブルーチン呼び出し
}
サブルーチン{
呼び出し元の変数使用
}
みたいに
732 :
デフォルトの名無しさん:2005/08/06(土) 21:46:08
またきた・・・
>>731 無理。
そういうのはインタプリタ言語じゃないと難しいと思う。
>>731 サブルーチン内のstatic変数とかじゃダメなん?
サブルーチンって懐かしい言葉だな
つか引数でわたしゃいいんじゃねーの?
まず考えるのは引数で参照(or ポインタ)渡しじゃないの?
スタックさかのぼるとか
「サブルーチンからだけは見える」は実現できないけど
>>731 擬似的に
void func() {
struct {
int internal;
void routine() {
hoge(internal);
}
} sub;
sub.routine();
}
>>733-740 マルチすまん
なんか難しそうなことはわかった
素直に参照渡し使うことにする
742 :
デフォルトの名無しさん:2005/08/07(日) 05:13:56
struct A
{
A* hello()
{
std;;cout _<< "Hello" << std::endl;
}
A* operator->()
{
std::cout << "A::oprator->()" << std::endl;
return this;
}
A* operator[](const std::string& s)
{
std::cout << "A::operator[]()" << std::endl;
return this;
}
A* operator()()
{
std::cout << "A::operator()()" << std::endl;
return this;
}
};
int main()
{
A a;
a->hello() //OK
a->(); //error
a->["hello"]; //error
}
operator->でA*を返してるはずなのにエラーになったりならなかったり
どういうことでしょうか? vc7.1です
>>742 a.operator->();
a.operator()();
>>742 operator []()は普通参照を返すけど。
なんでこう的外れなレスばっか出てくるんだろう。
夏休みだから。
>>742 ->の後にはメンバがなければならない。
[]や()はたとえオーバーロードしていようと演算子だから->の後には続けられない。
>>748 "operator"も書けば呼べなくもない
a->operator[]("hello");
751 :
デフォルトの名無しさん:2005/08/07(日) 14:17:44
かなり初歩的な質問ですいませんが教えてください。
特別バージョンに指定するtemplate<>ですが、どうしてこれを書く必要があるのかわかりません。
template<typename T>
class C {
// ...
};
//template<>
class C<int> {
// ...
};
下が上の特別バージョンであることをコンパイラは判断できないんですか?
>>751 回答じゃなくて悪いが、なんでこれが初歩的な質問だと思ったんだ?
753 :
デフォルトの名無しさん:2005/08/07(日) 15:12:40
>>751 下の書き方じゃ変数化したいintと普通のintの区別が付かないから
>>751 明示的インスタンス化の宣言が template class C<int>; だから、
class C<int>; だけの場合を許すとして、
明示的インスタンス化と見るか明示的特殊化と見るかを決めかねるんじゃないか?
>>752 なにぶんテンプレート初心者なもので。
>>753 テンプレート引数なのか型名なのか区別が付かないということでしょうか??
>>754 定義も一緒にする場合にはtemplate<>は付けなくてもいいということですか?
template<typename T> class C
{
public:
void f() {
printf("C<T>::f\n");
}
};
//template<>
class C<int> {
public:
void f() {
printf("C<int>::f\n");
}
};
void main() {
C<float> c1;
c1.f();
C<int> c2;
c2.f();
}
とりあえず上のプログラムをVSN2002でコンパイルしたら下のような出力になりました。
C<T>::f
C<int>::f
756 :
754:2005/08/07(日) 16:22:49
>>755 伝わらなかったみたいだな。ごめんよ。
class C<int>; を許すとして、
template class C<int>; と見るか、
template<> class C<int>; と見るか、
どっちにするか決められないんじゃないか、ってこと。
757 :
デフォルトの名無しさん:2005/08/07(日) 16:23:55
C++知らないんだけど、その二つはどうちがうの?
758 :
デフォルトの名無しさん:2005/08/07(日) 16:24:54
>>757 C++知らないのにどうしてここを見ているの?
759 :
754:2005/08/07(日) 16:30:01
あれ?
gcc 3.4.4 でも MSC でも class C<int>; が
明示的特殊化の宣言( template<> class C<int>; )として通った。
こんなの規格にあったっけ?
760 :
754:2005/08/07(日) 16:37:14
定義も加えようとする( class C<int> {}; )と、エラーになる。
gcc 3.4.4:
error: an explicit specialization must be preceded by 'template <>'
vctoolkit2003:
error C2906: 'C<int>' : explicit specialization requires 'template <>'
どちらも明示的特殊化として認識はできているが、
文法としては template<> が必要だからしょうがなくエラーって感じだな。
とりあえずtemplate<>は付けておかないとダメそうということはわかりました。
これは言語の仕様として必ず必要ということになってるんでしょうか?
それともコンパイラに依存するとなっているんでしょうか?
>>762 言語仕様として必要なんですね。
それだけわかれば良かったんです。
コンパイラの話にしてしまってすいません。
ありがとうございました。
>759
class C<int> なら構文的には forward declaration として認識されるような気がする。
規格書ちゃらっと見てみた限りでは friend 宣言で使われてたよーな。
>764 補足
セミコロンが抜けた。 class C<int>; ね。
で、friend class task<int>; って記述があったってことね。
>>764-765 構文として forward declaration などというものは存在しないわけで、何が言いたいのかわからん。
C++で使えるコルーチンライブラリってある?
>>767 Win32API Fiber Functions
>766
構文としては explicit-specialization じゃなくて単なる declaration であり、
解釈としては forward declaration として見なされるのではないか?ということです。
>>769 ISO/IEC 14882:2003にない造語で勝手に語らないでくれないか。
771 :
デフォルトの名無しさん:2005/08/08(月) 23:11:09
773 :
デフォルトの名無しさん:2005/08/08(月) 23:32:51
you too
>>769 ちょっと >759 を読み直してみろよ。
構文としては simple-declaration であるはずの class C<int>; が
explicit-specialization と同様に扱われているようだが、
そう扱うように規格で定められているのか?というのが問題なわけよ。
「forward declaration として見なされるのではないか?」なんてのは的外れ。
そもそも「forward declaration」という言葉の意味が
規格中で定義されていないので、この流れの中では意味不明。
>775
ごめん。
確かに的はずれで、explicit-specialization 「の宣言」 (14.7.3/2) が俺脳内 forward declaration そのものでした。
forward declaration については 9.1/2 で言及があるんですが、class-key identifier の場合なので template-id
である今回の場合はあてはまらない。
7.1.5.3 の elaborated type specifier で、かつ単一の構成要素なので 7.1.5.3/1 の場合だと思うんですが、
そうすると friend ついてないし、結局 explicit specialization か explicit instantiation じゃないとだめ。
でも template も template <> もついてないから、そっちもだめ。
この辺は friend class C<int>; を認めるために 14882:1998 から変更されてるみたいですが、
ttp://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#68 規格上は class C<int>; は ill-formed だというのが正しいんじゃないでしょうか?
コンストラクタ初期化子で
配列を初期化するのは可能なのでしょうか?
780 :
デフォルトの名無しさん:2005/08/09(火) 12:05:02
RGB → BGR 変換ってどうやったらいいでしょうか?
C++にはRGBもBGRもありません。
RGB→BGR変換って、
RGB old;
BGR new;
new.b = old.b;
new.g = old.g;
new.r = old.r;
ってこと?
どうやるもへったくれもなさそうなんだけど。
つまらんネタでひっぱらなくてよろし
Platform SDKがインストールできません。
Microsoft Platfrom SDK\Help\PSDK.hxq
というところで必ず停止します。仕方ないのでインストールをキャンセル。
あは先週の俺と同じところでひっかかってる。
たしかどこかにすべてローカルにDownしてからインスコできるモジュールが
あったのでそれを入手すればなんとか。
coreSDKあたりでぐぐればヒットする。
インターフェース用の抽象クラスa,bと、aを継承したAがある。
こんな状態で、aとb両方のインターフェースをもったクラスへのポインタを
引数として受け取るクラスCはどうやったら定義できるでしょうか。
つまりCは、a及びbを継承したクラスabと、A及びbを継承したクラスAbの
どちらも渡せるような物にしたいんです。
>>787 C は「クラス」じゃなくて関数の間違いですよね。
漏れなら単に void C(a*, b*) と引数を2つにするけど。
interface も2つに分かれてるんだしさ。
>>788 a,bのインターフェースを持った物ではなく、a,b両方のインターフェースを持ったものみ渡したいんです。。
>>789 それを1つの引数で済ませるようなことはしない、っていう意味。
4つも5つもinterfaceがあるならまた話は別だけど・・
791 :
デフォルトの名無しさん:2005/08/09(火) 20:53:57
>>787 struct ab : a, b { };
struct C : std::unary_function<ab&, void> { };
とかは?
template parameterで頑張ればa,bの両方を継承したclassのみを受け取り
それ以外はコンパイルエラーにすることもできるかもね
793 :
デフォルトの名無しさん:2005/08/09(火) 20:55:29
インターフェイス継承してるときは dynamic_cast も嫌だけど使う
これでどうだ。仮想継承にしなくても当然適切な関数が呼ばれるが一応そうした。
struct a {virtual void FuncA() = 0;};
struct b {virtual void FuncB() = 0;};
struct interface_ab : virtual public a, virtual public b {};
struct A : virtual public a {
void FuncA() {
std::cout << "A::FuncA" << std::endl;
}
};
struct ab : public interface_ab {
void FuncA() {
std::cout << "ab::FuncA" << std::endl;
}
void FuncB() {
std::cout << "ab::FuncB" << std::endl;
}
};
struct Ab : virtual public A, virtual public ab {
void FuncA() {
A::FuncA();
}
};
void c(interface_ab& hoge) {
hoge.FuncA();
hoge.FuncB();
}
int main() {
Ab obj;
c(obj);
}
a,bだけでなくさらにabも継承しないといけない解法か。。
>>790 両方の引数に同じポインタを渡すってコトですか?
それはちょっとかっこ悪い気がするんですが。。
>>791 関数オブジェクトを知らないので、使い方がよくワカリマセン。
Abとかは、その場合のab&にキャストできるんでしょうか??
>>794 自分もその方法は思いつきました。
が、仮想継承じゃないとコンパイルエラーが出たんですが、仮想継承じゃなくてもいけるんでしょうか?
仮想継承は遅いらしいので、この方法以外を探していたのですが。
>>796 >仮想継承は遅いらしいので
あんたのアプリで問題になるほど重いとはかぎらんだろ。
何故簡単に解決する方法があるのにそれを試さない。
っていうか設計が悪い気がする…
なんでそういうことをしたいのか理由が知りたい
今時仮想継承で遅いとか寝言いうやつがいるのか・・・
仮想継承で遅いか。マシンをグレードアップすれば済む話じゃないか。
801 :
デフォルトの名無しさん:2005/08/10(水) 09:38:01
やっぱりCが最高だよ。もうCに戻ろうよ。
>>787 単純に
void func_a_b(a *pa, b *pb)
{
pa->func_a();
pb->func_b();
}
template<typename T>
void func_ab(T *pab)
{
func_a_b(pab, pab);//T*はa*,b*へ変換できること。
};
みたいなのじゃだめ?
T* が a* と b* に変換できる場合だけコンパイルが通ると思うけど。
基本的に
>>788と同じだけど、一応呼び出し側は一つだけ渡せば済むということで。
既に型がa*だけとかb*だけとかになってしまっているのなら
dynamic_castなり何なりを使って動的に両方のインタフェースを持っていることを
確認するしか無いと思う。静的に確認する方法は無いよね。
こんにちは、
プリプロセッサによる条件文を記述しようとしているのですが、
Windows環境でのビルドだと、指定したインクルード(#include "MyWinApp.h")がされるようにしたいのです。
プリプロセッサに何をしていすればいいのでしょーか?
よろしくお願いします。
#ifdef ?
#include "MyWinApp.h"
#else
#include "MyApp.h"
#endif
>>803 スレ違い。環境依存。C++には定義されていない。
>>803 これだけのことじゃないのかな?
//#define WINDOWS //Winの時だけコメントから外す
#ifdef WINDOWS
#include "MyWinApp.h"
#else
#include "MyApp.h"
#endif
WINDOWS という識別子は変えた方がいいだろうけど
808 :
デフォルトの名無しさん:2005/08/11(木) 20:47:49
>>803 コンパイラのマニュアル嫁
某のコンパイラだと
__WIN32__と_Windowsが定義されてる
810 :
デフォルトの名無しさん:2005/08/11(木) 23:17:32
struct S { static int const zero = 0; friend int f(int a = zero); };
このデフォルト引数の指定がgcc(3.4.4 cygwin)でエラーになります。
error: `zero' was not declared in this scope
friendじゃない、普通のメンバ関数ならデフォルト引数の指定にzeroが使えました。
VCだと通るみたいなんで、gccのバグでしょうか?
811 :
デフォルトの名無しさん:2005/08/11(木) 23:19:44
なんつーか、gccが正解。
VCの方がむしろ拡張。
>>811 それだと、こっちもエラーにならないとおかしいんじゃないですか?
struct S { static int const zero = 0; friend int f() { return zero; } };
こっちはgccでもVCでもエラーになりません。
>>810 , 814
規格とかよく知らんが、少なくとも漏れの目には810と814でf()のスコープが違うように見えるが。
816 :
デフォルトの名無しさん:2005/08/12(金) 00:45:11
メンバ関数ポインタについて教えてください。
class A {
func(int i); // 1
func(double d); // 2
};
の2のポインタが欲しいときはどうすればいいのでしょうか。
そもそもそれ戻り値の型ないじゃん
戻り値型が書いてないが
819 :
816:2005/08/12(金) 00:49:47
ごめんなさい。あせりました。
メンバ関数ポインタについて教えてください。
class A {
void func(int i); // 1
void func(double d); // 2
};
の2のポインタが欲しいときはどうすればいいのでしょうか。
あとスコープがprivateだと実例が出しにくいと思われ。
で、どうすんだろ、オーバーロードされてっから関数名じゃ特定できないな。
なるほど,オーバーロードしているんですな.型は以下のとおり.
void (A::*)(int); // 1
void (A::*)(double); // 2
で,
void (A::*pmf1)(int) = &A::func; // pmf1という変数に1へのポインタを代入
void (A::*pmf2)(double) = &A::func; // pmf2という変数に2へのポインタを代入
へぇ、型に合わせて選択してくれるんだ。
しらんかった。
823 :
816:2005/08/12(金) 00:56:26
ありがとうございます。
変数の宣言のしかたで区別してもらえるんですね。
やってみます。
>>820 オーバーロードされている関数のポインタを取る場合,
代入先の変数の型によってあいまい性が解消されるという規則があります.
static_castのような明示的なキャストによる曖昧性の解消も可能です.
static_cast<void (A::*)(int)>(&A::func); // 1へのポインタを指定
static_cast<void (A::*)(double)>(&A::func); // 2へのポインタを指定
825 :
816:2005/08/12(金) 03:45:33
やりたかったことができました。
ありがとうございました。
ご報告まで。
フレンド関数てどんな場合に使うんですか?
普通に設計してればいらない気がするんですが・・・
横着したいとき用というわけでもないですよね
>>826 唯一使っても良いと思えるのはクラスに対するオペレーターオーバーロードだけだね。
行列とベクトルの乗算にoperator*をフレンドでオーバーロードするのは
使い道なしってことですか。
クラスメンバのoperator *=()を呼ぶようにすればってのはだめか?
>>815 810も814も f() はグローバルで同じスコープだろ。(両方とも ::f() )
マジレスしてやりたいが、「普通の設計」という予防線がある以上
何言っても設計が悪いではねられそうで警戒しちまうなw
乱発は良くないですねとしか言いようがない。俺はたまに使ってるけど
friendはカプセル化に穴を開けるから、原則として使ってはいけないと
思いこんでる香具師大杉。
「C++の設計と進化」P64を嫁。
後藤と同じ類だな
質問です
int main ()
{
char *pBuffer;
pBuffer = new char *[5]; // char * 型のメモリを確保
pBuffer[0] = new char[20]; // ↑で確保したメモリのひとつにchar型のメモリを確保
strcpy(pBuffer[0], "Helo C++ World"); // 確保したchar型のメモリに文字列を入れる
cout << pBuffer << endl;
delete [] pBuffer[0];
delete [] pBuffer;
return 0;
}
上のように、キャラポインタ型のデータを確保して、
その確保したデータに文字列を入れたいのですが、
pBuffer = new char *[5]; // char * 型のメモリを確保
ここで引っかかってしまいます。
char*型のメモリって、確保できないんでしょうか?
どなたかどうかお願いします m(__)m
char **pBuffer;
pBuffer = new char *[5]; // char * 型のメモリを確保
pBuffer[0] = new char[20]; // ↑で確保したメモリのひとつにchar型のメモリを確保
strcpy(pBuffer[0], "Helo C++ World"); // 確保したchar型のメモリに文字列を入れる
cout << *pBuffer << endl;
delete [] pBuffer[0];
delete [] pBuffer;
すいません、自己解決?しちゃいました・・
char **pBuffer;
ってやったら、うまくいっちゃいました。
これで正しいでしょうか?
>>839 × char* pBuffer;
× char** pBuffer;
char ** pBuffer;
× char* pBuffer;
○ char** pBuffer;
あとstrcpyじゃなくてstrncpy使ったほうがよさげ
更に言うとメモリ管理めんどくさくなりそうだからクラス化しちゃえば・・・?
>>841 どうもありがとうございます m(__)m
>>840の
cout << *pBuffer << endl; は
cout << pBuffer[0] << endl; の方が正しいかも
>>842 ああ、すみません。
>>843 うはwwごめんなさい。
関係ないですけど、アスタリスクは
多数派 char* pBuffer
少数派 char *pBuffer
あんま見ない char * pBuffer
なんですね ^^
>>843 今クラス化の途中です。
strncpy()はstrlen()も一緒に使うんでしょか?
>>845 strncpyで指定する長さは確保したサイズであって文字列自体のサイズじゃない
それ以上書くなって意味。buffer overflow予防。
というかstringとvector使えば終了・・・
848 :
デフォルトの名無しさん:2005/08/12(金) 19:55:14
>>845 俺は本音は少数派で普段は多数派に迎合
メンバポインタとか多数派じゃ無理
>>846 あー、なるほど。納得。
もし
>>839のだと、
strncopy(pBuffer[0], "Helo", strlen("Hele") + 1);
って書かなきゃならないから、なんかおかしいと思ったのですが、
strncopy(pBuffer[0], "Helo", 20);
って書けば有事の際にもオーバーフローしなくなりますね。
でもサイズが合わないとヌル文字は入らないとかなんとか・・。
>>847 orz
>>848 迎合てww そですかww
メンバポインタってのはよくわからず。
classの中で実質同じだけど異なる名前の変数を使いたいときってどうするの?
class CCCC
{
int a;
int *a_ailias;
CCCC():a_ailias(&a){}
};
もっとスマートな方法ないのかな
>>849 > strncopy(pBuffer[0], "Helo", strlen("Hele") + 1);
> strncopy(pBuffer[0], "Helo", 20);
まあ、あくまで一例の話だし、細かいこと言うのはアレだけど
char pBuffer[] = "nulupo";
char* src = "Helo";
strncpy(pBuffer, src, (sizeof pBuffer/sizeof pBuffer[0]));
かっちりやるならこうだろ。
pBuffer[0]へコピーとか、"Helo"だの20だのハードコーディングとか、ポインタと配列の区別とか、まあ頑張れ。
ちなみにメンバポインタってのはこういうヤツ。
void (IInterface::*pMethod)() = CSomeClass::someMethod;
(pObj->*pMethod)();
>>850 そんな感じでポインタか参照使うしかないんじゃね?
何がしたいのかにもよるだろうけど。
>>851 >char* src = "Helo";
const付けろよ。
strncpy()は、バッファが足らないときの動作があれなんで、俺は使わない。
そうだな、使うなら、strncpyよりは、snprintfだなぁ。
>>853の言う問題はsnprintfでも解決されないと思うが。
予めバッファの最後に'\0'入れといて、バッファサイズ-1渡せばいいだけじゃん。
>>850 「別名」を使うなら参照(int& a_alias)を使うんじゃないかな。
ポインタでも実質ほとんど変わらないだろうけれど、参照にはNULLがない・参照先は変えられない分すこし安全。
strlcpyを使うのが通
staticで宣言した変数は自分のタイミングで消せる?
消せぬ
_, ,_ パーン
( ‘д‘)
⊂彡☆static
車輪の再開発なんてしないでstring使えよ
「用意しているバッファより長い文字列がきたら切り捨てる」という処理をする
シュチュエーションがあまりないから、strncpy()はあまり使いどころがないような。
もしそういう処理なら、strncpyを使って、バッファの最後に必ず0を書き込むという
処理でいいかもしれないけど。
バグを利用してスタックを書き換えるとか、セキュリティーを意識して、strncpy()が
推奨されてるのだろうか。
バッファの最後というか、バッファの余りを0で埋める、というのが正確じゃないのかな。
866 :
デフォルトの名無しさん:2005/08/12(金) 23:18:19
>>859 クラスユニークな変数を臨機応変に生成 / 削除したいなら
static なポインタを定義して new / delete すればええやん
マルチスレッドんときはブロック処理して
今なら解決してるって安心できるのか?それ
870 :
デフォルトの名無しさん:2005/08/12(金) 23:45:26
>>867 もう少しトゲのない文章は書けないのかね?
>>867がそれのどこを読んでレスしてるのかがわからんが、
少なくともWIN系ではそのままじゃ使えないな
#define snprintf _snprintf みたいなことをしなきゃならん
strncpy()ってのはいわゆるsubstr()相当の使い方をするものだと思っていた。
string.hって文字列操作用の関数群であって、文字列用バッファ管理をするものではないという認識で居たんだが、プロの世界ではstring.hにあるような関数を直で使ってバッファ操作を行うのか・・・
>strncpy()ってのはいわゆるsubstr()相当の使い方をするものだと思っていた。
その使い方だと、最後にNULが埋まらない場合が多い気がするけど。
874 :
デフォルトの名無しさん:2005/08/13(土) 07:01:50
クラスA、クラスBがあります。両方ともクラスCから派生しており、
クラスCはメンバ変数としてvoid(*m_pfunc)(int)という関数ポインタを持ち、
Set〜,Get〜という感じでそのポインタのセッターゲッター関数もあります。
クラスAはメンバ変数としてクラスBへのポインタを持っています。
クラスAのコンストラクタでクラスBをnewして、
クラスAのメンバ関数void func(int) へのポインタを
クラスBに渡したいのですが、可能でしょうか?
とすればどう書けばよいでしょうか。教えてください。
>>874 メンバ関数 void func(int) へのポインタは void (*m_pfunc)(int) とは型が違うぞ。
それ以外の情報は関係ない。型をあわせない限り無理。
876 :
デフォルトの名無しさん:2005/08/13(土) 07:24:53
>>875 戻り値voidで引数intな型の関数(とそのポインタ)のつもりだったんですけど、
どう違いますでしょうか。
メンバ関数とそれ以外の関数という点が違う
878 :
デフォルトの名無しさん:2005/08/13(土) 07:42:10
その違いが分からないので渡し方が分からずに質問している次第であります。
879 :
デフォルトの名無しさん:2005/08/13(土) 07:51:52
普段は外の(グローバルな?)関数へのポインタを渡して使っているのですが、
クラスA内で生成するクラスBの、このインスタンスには
特別にクラスAのメンバ関数へのポインタを渡したいのです。
メンバ関数と外の関数の両方に対応させるというのは不可能な事なのでしょうか?
不可能です
881 :
デフォルトの名無しさん:2005/08/13(土) 08:17:37
マジですか。
メンバ関数へのポインタってのは取れないんですか?
クラスごとにそれぞれ.cppと.hファイルを作ってるんですが、
クラスAの定義の外側に普通の関数として書いてそのポインタを渡せば
とりあえず目的は達成できると思いますが、なんか汚いというか気持ち悪いです。
こういったケースの場合どうするのがいいでしょうか。
882 :
デフォルトの名無しさん:2005/08/13(土) 08:24:39
>>874 void(A::*m_pfunc)(int)
この場合、C の宣言に A が出てくることになるが、いいのか?
メンバ関数へのポインタは普通のポインタの逆でアップキャストができない
>>881 メンバ関数ポインタの使用に固執するなら、まあ、クラスBにクラスAの
メンバ関数ポインタ型のメンバと、それを初期化するコンストラクタを書く
のがまともな手だとおもうが
それがいやなら、静的メンバ関数は、通常の関数ポインタに渡せるから、
そこら辺で妥協すれば?
メンバ関数はやめて、、代わりにメンバに関数オブジェクトを持ったら?
>881
>クラスAの定義の外側に普通の関数として書いてそのポインタを渡せば
それで済むようなものは非静的メンバ関数である必要はないんじゃないか?
つまり >883
>それがいやなら、静的メンバ関数は、通常の関数ポインタに渡せるから、
>そこら辺で妥協すれば?
886 :
デフォルトの名無しさん:2005/08/13(土) 12:55:47
いろいろありがとうございます。
>>885 一応クラスで全部ラッピングしたいのと(一個だけ外にあると気持ち悪い)、
ライブラリっぽくしたいので、グローバルな関数を使用して
それを外からよばれたりすると困らないかなと思いまして。
staticな関数にするとstaticなメンバにしかアクセスできないし、
この関数一つのためにクラスBにAの宣言を書くのも気持ち悪いなと。。。
グローバルにしながら外から呼べなくする方法というのはありますでしょうか?
(今は関数オブジェクトというのについて調べてます)
887 :
デフォルトの名無しさん:2005/08/13(土) 14:36:00
別に B に A の宣言が入ってる必要も operator () () も必要ないやん
template <typename T> struct C { void (T::*m_pfunc)(); };
template <typename T> struct B : C<T> { };
struct A : C<A>
{
B<A>* b;
A()
{
b = new B<A>;
b->m_pfunc = &A::func;
}
void func() { }
};
>>886 関数ポインタとメンバ関数ポインタの違いとか、
>staticな関数にするとstaticなメンバにしかアクセスできないし、
の理由とか、分かっているのかな。
関数オブジェクトについて調べるより、そっちの方が先だと思う。
その辺が分かれば答えは自ずと見えてくると思うんだけど……。
こういうのって色々やり方があって、状況に応じて使い分けているから
一概にこれ、とは言いづらいんじゃない?
>>887 >>879 >普段は外の(グローバルな?)関数へのポインタを渡して使っているのですが、
>..snip..
>メンバ関数と外の関数の両方に対応させるというのは不可能な事なのでしょうか?
らしいよ。
#Boost.Functionと言いたくても我慢してる自分
関数オブジェクトにするにしても、クラスCのメンバ変数1つに格納するんじゃ、
二工夫ぐらい必要だし、キャスト必至で使いにくそう
>>874 というわけで、関数オブジェクトならぬ関数ホルダーを使った実装w
本質的に無関係なんで、AのB型ポインタ・メンバはオブジェクトに変えさせてもらった
これで要望は満たしていると思うが、いかがか?
VC++7.1 で確認済み
#include <iostream>
#include <memory>
struct FuncHolderBase { virtual FuncHolderBase* clone() const = 0; };
template<typename Func>
class FuncHolder : public FuncHolderBase {
Func func_;
public:
FuncHolder(Func f) : func_(f) {}
FuncHolder<Func>* clone() const { return new FuncHolder<Func>(func_); }
operator Func() { return func_; }
};
(続く)
class C {
std::auto_ptr<FuncHolderBase> fb_;
typedef void(*Func)(int);
public:
void set(Func f) { fb_.reset(new FuncHolder<Func>(f)); }
void set(FuncHolderBase const& fb) { fb_.reset(fb.clone()); }
template<typename T> T& get() { return static_cast<T&>(*fb_); }
FuncHolder<Func>& get() { return get<FuncHolder<Func> >(); }
};
struct B : public C {};
class A : public C {
typedef void(A::*MF)(int);
B b_;
void print(int n) { std::cout << "Member: " << n << std::endl; }
public:
A() { b_.set(FuncHolder<MF>(&A::print)); }
void foo(int n) {
(this->*b_.get<FuncHolder<MF> >())(n); }
};
void print(int n) { std::cout << "Normal: " << n << std::endl; }
int main()
{
B b; b.set(&print); b.get()(1);
A a; a.foo(2);
}
892 :
890:2005/08/13(土) 18:18:07
「導出」という言葉を思い出してちょっといじったら、もっとシンプルになりやがりました
テンプレートって侮れねえ.....orz
893 :
874:2005/08/13(土) 20:55:56
皆さんいろいろありがとうございました。
ちょっと今の自分のレベルだと難しそうなので、
とりあえずきれいではない方法でベタに書いておきます。
いろいろキーワードを頂いたので、もうちょっとレベルが上がったら
見れるようにログを保存しとこうと思います。
(
>>892よかったらあとで参考にしたいので教えてください。)
ありがとうございました。
894 :
892:2005/08/13(土) 21:59:31
>>893 じゃあ、挙げとく
struct FuncHolderBase {};
template<typename Func>
class FuncHolder : public FuncHolderBase {
Func func_;
public:
FuncHolder(Func f) : func_(f) {}
operator Func() { return func_; }
};
class C {
std::auto_ptr<FuncHolderBase> fb_;
typedef void(*Func)(int);
public:
template<typename T>
void set(T f) { fb_.reset(new FuncHolder<T>(f)); }
template<typename T> T get() { return static_cast<FuncHolder<T>&>(*fb_); }
Func get() { return get<Func>(); }
};
class A : public C {
typedef void(A::*MF)(int);
B b_;
void print(int n) { std::cout << "Member: " << n << std::endl; }
public:
A() { b_.set(&A::print); }
void foo(int n) { (this->*b_.get<MF>())(n); }
};
後は890-891と同じ
895 :
874:2005/08/14(日) 10:07:57
>>894 ありがとうございました。まだ意味もよく分からぬままですが
とりあえずいじってみようと思ってコンパイルしてみたところエラーが出ました。
VC6++なんですが、なんかコンパイラの原因でしょうか。
error C2275: 'C::Func' : typedef 識別子に、クラス メンバ アクセス演算子 (->) を使用しました。
error C2059: 構文エラー : ')'
error C2783: 'T __thiscall C::get(void)' : 'T' 用のテンプレートの引数を減少できませんでした。
warning C4508: 'main' : 関数に戻り値の型が指定されていません。戻り値を void 型と見なします。
VC6.0 は、糞
>>896 るせーToolkit使ってるおれはどうなる
898 :
デフォルトの名無しさん:2005/08/14(日) 10:31:46
VC6 くらいでガタガタ騒ぐ奴こそ世間を知らなさすぎる甘ちゃんだ
むしろそれこそが
世間の端っこにばかり居て中道の感覚を知らない
うらぶれたおっさんの言動w
企業だと、普通にVC++6.0使ってるけどね。
下手するとVC++5.0使っている場合もあるよ。
でも糞は糞。糞だと理解しながら何とか使っていくのがプロ。
使っているからって糞じゃないとか言い出すのは、日々の土方労働で
感覚がすっかりズレてしまった阿呆。
そして皆分かりきっていることを得意げに脊髄レスしてスレの方向をずらす阿呆
>>896
903 :
874:2005/08/14(日) 11:52:01
つまり、新バージョンを買えということでしょうか?
コンパイラの問題だから修正しようがない、ってことでOKですか?
>901 がプロらしいから、>895 に答えてあげて欲しいな。
VCTK落としてコンパイラだけ差し替えれ。
あ、デバッガ使えなくなるんだっけ?覚えてないけど。
コンパイラをコードに合わせるかコードをコンパイラに合わせるかの問題だから
財布と相談しろとしか言いようがない。
907 :
874:2005/08/14(日) 12:29:02
VC6用に書き換えるとしたらどうなるんでしょうか。
なにが引っかかってエラーになってるのか分からないんですが。
WindProcごときでいつまでもグダグダいってんじゃねぇ。
909 :
デフォルトの名無しさん:2005/08/14(日) 14:13:45
いつのまにかboost-1.33が出てるじゃん
それにサイトもリニューアルしてるし
910 :
デフォルトの名無しさん:2005/08/14(日) 14:21:21
>>903 違う
あなたが悩んでいることは純粋に設計の問題であって
コンパイラのバージョンは関係ない
何をどうしたいのかを、まずはっきりさせなさい
それでもし書けないことがあったら、
本質的に無理なことか、そうではないかをはっきりさせなさい
本質的に無理なこととは、アセンブラでもハードでも絶対に無理なことを言う
911 :
874:2005/08/14(日) 15:08:39
↑とりあえず、「なさい」じゃねーよ。
教える立場、教えてもらう立場って前にあかの他人同士だっていう関係性を忘れんな。
テメェが威張る場面じゃねーんだよ。
偉そうな事抜かす前に話の流れくらい読んでから書き込めや糞馬鹿が。
夏ですね〜^^
駄目だこりゃ
感動してしまった
夏だね〜
流石に騙りだろ?
917 :
デフォルトの名無しさん:2005/08/14(日) 16:32:42
もう死にたい
918 :
874:2005/08/14(日) 16:51:53
コンパイラの問題らしいので別スレで聞いてきました。すいません。
>>902 わからない人がいるみたいだから
説明してあげたんですよ。
もうわかりましたか?
>>919 何も説明してないじゃん
これだから池沼は困る
あ、本物のキチガイさんでしたか。
早くよくなってくださいね。
922 :
デフォルトの名無しさん:2005/08/14(日) 19:44:46
こんにちは、よろしくお願いいたします。
char *a;//char型のポインタにはいったもじを
string aa;//string型の変数に代入したいのですが、
どうすればよいのでしょうか。
for(int i = 0;i<sizeof(a);i++){
aa += *a;
a++;
}
このようにすると、
仲良し 織
では、仲良 しか、はいりません。
aa = a;
色々マニアックなやり方してますね^^
925 :
デフォルトの名無しさん:2005/08/14(日) 20:15:03
std::wstringをstringとかchar* の文字列に変換したいのですが
どうしたらよいでしょうか。
926 :
925:2005/08/14(日) 20:44:28
STLスレがありましたので逝って来ます。
927 :
785:2005/08/14(日) 21:46:12
>>785 ISOイメージ版をDLして
Daemon Toolsでマウントしてインストールしたとです
(FULL DONWLOAD版は使用方法不明)
928 :
デフォルトの名無しさん:2005/08/14(日) 21:59:58
>>923さんありがとうございまいた
できました。
>>924さん
そうですね。とてもへんなことしてたのですね。
VC++2003はシェアウェアをつくってもいいのですか?
まじですか
サポートに電話して聞いても詳しく教えてくれなかったので・・・
明日買ってきます
>>933 どこにかけたんだ? MSのサポートはちゃんとそーゆー事にも答えてくれるぞ。
あ、でも、同じ番号にかけても馬鹿がでた場合はダメダメだったりするから、そーゆーこともあるかwwww
MSマンセーキタコレ
>>934 MSへですよ
うーん、電話の内容をここに転載してもいいのでしょうか?
一言一句正しく書かないと怖いことになりそうです
よろしく
>>937 いらない。スレ違い。
やるならどっか他所でやれ。
940 :
デフォルトの名無しさん:2005/08/15(月) 02:01:50
PS2のソフトを作りたいのですけど、さんこうになるHPしりませんか?
>>940 IBM PS/2のソフトならTurboC++1.0でも落としてくれば?
プレステ用って、ソニーと契約した会社にだけ
SDKとかが供給されるんでなかったか?違ったかな?
PS2 Linux使えば一応一般人でもPS2用プログラムは作成可能。
つか、あれはドキュメントが全てやけど。
これって勝手に売っていいのか?(゚Д゚;)