■過去ログ置き場に戻る■
1-
次250
最新50
[memo]
"9999999999_00.html#R20"
という感じで、URLの最後に "#R
レスNo
" を追加すると幸せになれます。
C++相談室 part7
1
名前:
デフォルトの名無しさん
:02/05/19 14:43
(´∀`).。o(関連URLは
>>2-5
の辺り)
2
名前:
デフォルトの名無しさん
:02/05/19 14:44
Boost
http://www.boost.org/
STLport
http://www.stlport.org/
過去ログ
Part1
http://piza.2ch.net/tech/kako/980/980175292.html
Part3
http://pc.2ch.net/test/read.cgi/tech/1003832761/
Part4
http://pc.2ch.net/test/read.cgi/tech/1009071535/
Part5
http://pc.2ch.net/test/read.cgi/tech/1014217496/
part6
http://pc.2ch.net/test/read.cgi/tech/1018454705/
Windowsの話はこちらで
Win32API 質問箱 Build3
http://pc.2ch.net/test/read.cgi/tech/1017072275/
Windows Programing for C/C++(Not MFC)
http://pc.2ch.net/test/read.cgi/tech/1018239290/
キタ?
C++ Final Draft International Standard
http://www.kuzbass.ru/docs/isocpp/
v(^▽^)v
Loki
http://www.moderncppdesign.com/
3
名前:
デフォルトの名無しさん
:02/05/19 14:46
VisualC++相談室 【7】
http://pc.2ch.net/test/read.cgi/tech/1017843192/
4
名前:
デフォルトの名無しさん
:02/05/19 17:47
>>1
乙彼
5
名前:
デフォルトの名無しさん
:02/05/19 19:24
(・∀・) オツカレ-
6
名前:
デフォルトの名無しさん
:02/05/19 19:57
>>1
http://www.cis.temple.edu/~ingargio/refman.pdf
次からはこれもテンプレよろしく
7
名前:
デフォルトの名無しさん
:02/05/19 20:39
v(^・^)v
8
名前:
デフォルトの名無しさん
:02/05/19 21:02
>>6
そこ、Forbiddenになっちゃうんだけど。俺だけ?
9
名前:
デフォルトの名無しさん
:02/05/20 03:55
http://photon.poly.edu/~hbr/cs903/c++/C++-ansi.pdf
じゃぁ、ここをどうぞ
10
名前:
デフォルトの名無しさん
:02/05/20 04:49
C++的にはクラスを名前空間代わりに利用するのってアリなんでしょうか?
自分の算術クラスを見てみたら、
class xMath {
private:
xMath(const xMath&);
operator=(const xMath&);
~xMath();
private:
inline static 〜
inline static 〜
};
こんな風になってたんだけど・・・
namespaceで書き直した方がいいですか?
11
名前:
デフォルトの名無しさん
:02/05/20 04:49
age
12
名前:
デフォルトの名無しさん
:02/05/20 05:14
VC++使ってます。
下のソース、メンバ関数Fの宣言と定義を同時にやらないと通らないのですが、
下に書いたように分離するのは仕様違反なのでしょうか?
struct S
{
typedef char type;
};
template<typename T>
class C {
public:
typedef T type;
static void F(type::type* p);
};
template<typename T>
void C<T>::F(type::type* p)
{
p;
}
S::type a;
C<S>::F(&a);
13
名前:
デフォルトの名無しさん
:02/05/20 08:25
クラス内はある種の名前空間で区切られているけど
普通の名前空間で済む話なら普通のでいんじゃない?
14
名前:
デフォルトの名無しさん
:02/05/20 09:48
>>12
標準仕様では OK のはず。ただし、type::type の前に typename が
必要だと思うけど。VC++ は template 機能が貧弱だから。
15
名前:
デフォルトの名無しさん
:02/05/20 10:08
typedef true T;
typedef false F;
とするとエラーになるんですが、だめなんでしょうか?
16
名前:
デフォルトの名無しさん
:02/05/20 10:12
true/false は型じゃないぞよ
17
名前:
16
:02/05/20 10:15
つか、true/false に別名をつけようとしてる時点で終わってるな…
18
名前:
16
:02/05/20 10:17
そうか、C とかからの移植作業ならそれもアリだな…
一人相撲つかれた。逝ってくる
19
名前:
デフォルトの名無しさん
:02/05/20 10:21
ん、ありなのか?
20
名前:
デフォルトの名無しさん
:02/05/20 10:21
>>16
, サンクス〜
型の時がtypedef で上の場合は#define使うのか。
typedef TRUE T;
が通ってたので勘違いしてました。
21
名前:
デフォルトの名無しさん
:02/05/20 12:00
template<typename T> class CTest
{ friend bool operator ==(const Test<T>& t1,const Test<T>& t2); };
//CTestをcharに特殊化
template<> class CTest<char>
{ friend bool operator ==(const Test<char>& t1,const Test<char>& t2); };
上の二つのクラスに、別々のoperator == をつけようと思い、
(1)か(2)の方法でクラス外で定義して、クラスにはfriendで実装
しようと思ったのですが、どちらもエラーになります。
これは不可能なことなのでしょうか?
(1)クラス外の関数の特殊化を試みる > Error!
template <typename T> bool operator ==(const Test<T>& t1,const Test<T>& t2)
{return true;}
template <> bool operator ==(const Test<char>& t1,const Test<char>& t2)
{return true;}
(2)別々に operator を作る。 > Error!
(クラス外定義なのでオーバーロードできないみたい)
bool operator ==(const Test<int>& t1,const Test<int>& t2)
{return true;}
bool operator ==(const Test<char>& t1,const Test<char>& t2)
{return true;}
22
名前:
21
:02/05/20 12:29
なんか勘違いしてました。
(2)はOKです。なんか違うエラーみたいでした。
23
名前:
デフォルトの名無しさん
:02/05/20 12:29
======2==C==H======================================================
2ちゃんねるのお勧めな話題と
ネットでの面白い出来事を配送したいと思ってます。。。
===============================読者数:105420人 発行日:2002/05/020
どもども、ちょっぴりワキガのひろゆきですー。
いやぁ、もうすぐですねー、谷澤動物病院の裁判の判決ですー。。。
おいらはいつものとおり、
「投稿者がわからないので勝手に削除は出来ない」
「勝手に削除したら投稿者に訴えられてしまうかも知れないから削除は出来ない」
との主張を繰り返してきたんですけど、裁判官てば実に冷ややかな目でおいらを見るんですよー。。。
その上、
「削除出来ないんじゃなくてするつもりがないんじゃないですか?」
「悪質な書き込みをむしろ売り物にしてるんじゃないですか?」
「発信者を特定出来るようにようにしてから能書きを語るったらどうですか?」
なんて嘲りの笑みを浮かべながら言うんですよー。。。
本当に憎らしい奴ですー、、うぅうぅ、、
ところで、谷澤動物病院てば、おいらのことを訴えてから客が2割も減ってしまったそうですー。。。
おいらのことを訴えると被害が余計に拡大するってことですね。。。えへへ。。。
んじゃ!
24
名前:
デフォルトの名無しさん
:02/05/20 12:30
>>21
仮引数のTestって?
CTestじゃないの?
25
名前:
デフォルトの名無しさん
:02/05/20 12:47
>>21
使ってるコンパイラは何?
26
名前:
21
:02/05/20 14:01
>>24
ミスって書き込んでました。どっちかに統一して見て。
>>25
VC.NET と VC6
でちょっと変えて実験してみたところ、VC.NETは下のはコンパイルできませんでした。
VC6の場合はコンパイルするのになんかコツがいるみたい。(^^;
(場所1から場所2)をコメントアウトして
一度ビルドして、コメントをはずして、改行を入れると、なぜかコンパイルできる。
やっぱり、operator == 系の特殊化は無理なのかな。
template<typename T> class Test :public T
{
friend bool operator ==(const Test<T>& t1,const Test<T>& t2);
};
template<> class Test<CString>
{
public:
friend bool operator ==(const Test<CString>& t1,const Test<CString>& t2);
};
template<> class Test<CWnd>
{
public:
friend bool operator ==(const Test<CWnd>& t1,const Test<CWnd>& t2);
};
template <typename T> bool operator ==(const Test<T>& t1,const Test<T>& t2)
{
return true;
}
//****場所1
bool operator ==(const Test<CString>& t1,const Test<CString>& t2)
{
return true;
}
bool operator ==(const Test<CWnd>& t1,const Test<CWnd>& t2)
{
return true;
}
//******場所2
27
名前:
デフォルトの名無しさん
:02/05/20 15:50
// これならコンパイルできると思う
>>26
#include <iostream>
template<typename T> class Test;
template <typename T> bool operator ==(const Test<T>& t1,const Test<T>& t2);
template<> bool operator ==(const Test<int>& t1,const Test<int>& t2);
template<typename T> class Test
{
friend bool operator ==(const Test<T>& t1,const Test<T>& t2);
};
template<> class Test<int>
{
friend bool operator ==(const Test<int>& t1,const Test<int>& t2);
};
template <typename T> bool operator ==(const Test<T>& t1,const Test<T>& t2)
{
std::cout << "template" << std::endl;
return true;
}
template<> bool operator ==(const Test<int>& t1,const Test<int>& t2)
{
std::cout << "specialization for int" << std::endl;
return true;
}
int main()
{
Test<int>() == Test<int>();
return 0;
}
28
名前:
デフォルトの名無しさん
:02/05/20 18:53
クラスのプリフィックスってどんなのつけてます?
ちなみに
メンバにはm_
静的変数にはg_
intにはn
charにはc
shortにはs
longにはl
unsignedにはu
とか付けてます。
29
名前:
デフォルトの名無しさん
:02/05/20 19:30
>>28
メンバは m_
static は s_
global は g_
あとは普通は型に対応させたりはしない。名前からだいたい分かるようにしてる
(〜Nameなら文字列(std::string)だろう、〜Counterなら整数だろう、とか)
しかしメンバは m_ とかかったるいので
postfix で _ というのも少しすっきりして良さそうな気もしてきてる
30
名前:
デフォルトの名無しさん
:02/05/20 20:07
あ、そうね
プレフィックス付けた方が見やすいか・・・
気をつけよう。
# サフィックスでもいいのかな?
31
名前:
デフォルトの名無しさん
:02/05/20 20:14
ポインタにpはつけてるな。
m_はでかいクラスで、引数と名前の衝突が起こりそうなとき。
pXxx;
m_pXxxx;
32
名前:
デフォルトの名無しさん
:02/05/20 20:27
MFCとかだとクラスの名前の先頭にCがついてますよね。
あとBuilderやDelphiなんかはTだとか。
>30
サフィックスって後ろに付けるということですよね?
それだと一目でわかりにくいような…。
33
名前:
デフォルトの名無しさん
:02/05/20 20:46
>>32
メンバ変数にアンダーバーをつけるなら、プレフィクス(前につける)は
マズい。それはC++の禁じ手。アンダーバーで済ませるなら、必ず
ポストフィクス(後ろにつける)で。
俺は、テンプレートクラス名の先頭にはT、例外クラスの先頭にはE、
それ以外のクラス名の先頭にはC、ってやってるなー。
インターフェースクラスの先頭をIにするかどうかは、いつも脳内会議中。
あと、char,short,longで区別じゃなくて、1バイト、2バイト、4バイトで
区別する、int8,int16,int32(もしくはBYTE,WORD,DWORD)をやってる。
34
名前:
デフォルトの名無しさん
:02/05/20 20:54
純粋な構造体としてのstructやenumには何かつける?
structはS enumはEとかつけようと思っても、
なんか最後の方でみんな取っちゃったりして。
35
名前:
デフォルトの名無しさん
:02/05/20 21:41
無修飾派。
MFC使ってるときは C とかVCL使ってるときは T とか付けたりするときもあるけど、基本は無修飾っす。鬱陶しいし。賛成の人?
36
名前:
デフォルトの名無しさん
:02/05/20 21:45
俺の場合、普通のクラスにはC、インターフェースクラスにはIを先頭につけた大文字小文字混じり。
structやenumには特につけない。
で、メンバやグローバル変数は大文字小文字を使って、ローカル変数は小文字のみ。
37
名前:
33
:02/05/20 21:54
>>34
構造体はSで始まるってイメージがないよなぁ。
size_t にしたがって、イメージがわきやすい「_t」を使ってる。
それにならって、enumは「_e」をつけてる。
38
名前:
デフォルトの名無しさん
:02/05/20 21:58
>33
すんません。
プリフィックスにアンダーバーを付けるとマズい(あるいは禁じ手)なのはなぜなんでしょう?
そういや、winだと標準で
INT8
INT16
INT32
UINT8
UINT16
UINT32
って用意されてますね。
39
名前:
デフォルトの名無しさん
:02/05/20 22:00
>>38
処理系(コンパイラベンダーなど)のために予約されている。
つまりはコンパイラのバージョンアップなどで _ で始まる新たな予約語などを
追加していいように、ユーザーはその名前を使わないようにとの決まり。
40
名前:
デフォルトの名無しさん
:02/05/20 22:47
>39
ああ、そういうことですか。
それはそうですね。
知ってました。
要するに
× _xXxxx
ですよね?
m_xXxxxがダメなのかと勘違いしてました。(w
デファインはよくアンダーバーを2回並べますが…。
41
名前:
デフォルトの名無しさん
:02/05/20 22:48
>>40
__ も予約されてるので駄目
42
名前:
デフォルトの名無しさん
:02/05/20 23:33
ついでにいえば、アンダースコアで始まる任意の名前 (つまり先頭にアンダー
スコアがいくつ並んでもよい) は、実装用に予約されている
43
名前:
デフォルトの名無しさん
:02/05/21 01:03
#define INC__HOGE_H
とか途中にアンダースコア2つもアウトだっけ。
44
名前:
デフォルトの名無しさん
:02/05/21 01:10
途中は問題ない
45
名前:
デフォルトの名無しさん
:02/05/21 02:08
クラスにいちいちCを付けるのは、個人的にちとダサイ気がするなぁ…。
ほとんどがクラスな訳だし、VCだとインテリセンスに掛かりづらいし。
むしろc的な使い方と両方やっている人が、区別のためにしてるのかな。
あとGoF本だと、メンバ変数のプレフィックスに _ 付けまくってるね。
あれは、可読性を高めるためにあえてやっているだけなのか、
それとも普段のソースそのものなのか…。
46
名前:
なぜ?
:02/05/21 02:24
以下のプログラムで、ストリームの状態のテスト
をしたいのですが、アルファベットを入力して
else節を実行しようとすると、無限ループになって
しまいます。何故に、cin >> i のところで次の入力
待ちになってくれないのでしょうか?
Borland C++ Compiler 5.5.1 と VC6.0 です。
OS はWin95
#include <iostream>
#include <string>
using namespace std;
int main()
{
int i;
cout << "整数を入力してください" << endl;
while(1){
if(cin >> i){
cout << i << ":読み込みに成功しました" << endl;
cout << "状態フラグ:" << cin.rdstate() << endl;
if(i == 0) break;
}
else{
cout << "読み込みに失敗しました" << endl;
cout << "状態フラグ:" << cin.rdstate() << endl;
cin.clear();
}
}
}
47
名前:
デフォルトの名無しさん
:02/05/21 02:37
ライブラリに入れちゃう一般化したクラスにはオリジナルの(漏れの場合はK)prefixつけてるな。
それ以外は、インターフェース(抽象クラス)にはIをつけるだけで、あとはつけない。
48
名前:
デフォルトの名無しさん
:02/05/21 03:51
すいません、激しく初心者で申し訳ないんですが
BorladC++のコンソールウィザードとやらで
簡単なプログラムを組んでみたんですけど、
自分のマシン以外だと「CC3250.DLL」が無いから動かないと言われます。
VCLを選んだら、VCL50が無いと言われました。
exeだけで、Win環境ならどこでも動くようにするのは
どうしればいいのでしょうか?
49
名前:
デフォルトの名無しさん
:02/05/21 04:11
>>48
プロジェクト→オプション→パッケージ→実行時パッケージを使って構築
プロジェクト→オプション→リンカ→共有RTLDLLを使う
この2つ共のチェックを外してコンパイル
50
名前:
sage
:02/05/21 04:13
スマソ。BCCね
コンパイラオプションで上と同じように設定できると思われ
51
名前:
48
:02/05/21 05:25
できましたー。ありがとうございます。
容量もそれらしく増えました。どーも8KBは変だと思ってました。
52
名前:
26
:02/05/21 07:14
>>27
やはり無理でした。
VC++.NETのMSDNのDeepC++ やテンプレートをいろいろ調べたところ。
次のようにするとスマートに解決できました。
enum TypeM
{
type_default = 0,
type_cstring = 1,
type_cwnd = 2
};
template<typename T,enum TypeM type=type_default> class Test :public T
{
public:
friend bool operator ==(const Test<T,type>& t1,const Test<T,type>& t2);
};
template<> class Test<CString>
{
public:
//friendの特殊化は無理みたい。>コンパイルできるが呼べない。
};
template<> class Test<CWnd>
{
public:
//friendの特殊化は無理みたい。>コンパイルできるが呼べない。
};
template <typename T,enum TypeM type> bool operator ==(const Test<T,type>& t1,const Test<T,type>& t2)
{
//typeは定数なので最適化時にswitchステートメントからは1つの関数が得られる。
//これがtemplateの最も優れた性質なのです。(MSDN参照)
switch(type)
{
case(type_cstring):
AfxMessageBox("CString");
break;
case(type_cwnd):
AfxMessageBox("CWnd");
break;
default:
AfxMessageBox("Default");
break;
}
return true;
}
53
名前:
デフォルトの名無しさん
:02/05/21 07:19
>>46
アルファベットは数字ではないので、int の i には読み込めないので、読み込まれずにいつまでも cin の中に残ってるから。
54
名前:
デフォルトの名無しさん
:02/05/21 07:42
int i;を
char c;にして
if(i==1) を if(c == '1')にする。
キーボードの 1 は文字で認識しないとだめ。
55
名前:
デフォルトの名無しさん
:02/05/21 07:45
>>53
>アルファベットは数字ではないので、
文字コードってご存じ?
56
名前:
デフォルトの名無しさん
:02/05/21 10:42
>>46
cin.clear(); の後に cin.ignore(); を呼ぶ。
>>55
?
57
名前:
デフォルトの名無しさん
:02/05/21 10:52
>>52
それだと Test<CString> には friend 関数が宣言されていないことに
なっちゃうけど…
58
名前:
デフォルトの名無しさん
:02/05/21 12:00
一画面に多くの行が収まり、全体の把握が楽なので、
今までこうコーディングしてました。
void func(){
//statement
}
しかし、ネット上で見かけるソースや、マイクロソフト関連の
サンプルをみると、最近ほとんどがこうです。
void func()
{
//statement
}
やはり後者が主流なのでしょうか?会社に入った場合はどちらが役に
立ちますか?くだらない質問ですが真剣です。ご教授頂ければ幸いです。
59
名前:
デフォルトの名無しさん
:02/05/21 12:16
>>58
クラス定義内のインライン関数なら前者の書き方でよいと思うが、
通常の関数定義は後者の方がよいと思う。
複雑な仮引数やtemplate文になると、頭だけで2行以上使うことも
あるぞ。
60
名前:
なぜ?
:02/05/21 12:30
すごい、cin.ignore()で上手くいった。
でも、これは何ですか?
cin.clear()でfailbitクリアするだけでは
駄目なんですか?
でも、ありがとうございました。うれしいです。
61
名前:
:02/05/21 12:34
テスト
62
名前:
デフォルトの名無しさん
:02/05/21 12:36
>>60
いや・・・・i に入れられなかったアルファベットがストリームに残った
ままになって永久ループするからだろ。ignore()はストリームをクリア
してくれる。
63
名前:
デフォルトの名無しさん
:02/05/21 12:38
>>62
・・・とと。ignore()は一文字だけ読みとるので、複数文字をいれると、
その一文字ずつメッセージが出てくるはず。
64
名前:
デフォルトの名無しさん
:02/05/21 12:42
>>59
レスありがとうございます。今までそういうのは
template<class T>
class<T>::func( int long_long_so_long_argment
int long_long_too_long_argment
char iikagennni_siro_argment ){
//statement
}
こんな感じにしてました。やはり就職すると、
最初の { の位置を書き直すよう、指導されたりするのでしょうか?
65
名前:
デフォルトの名無しさん
:02/05/21 13:04
>>64
たかが{の位置くらいで悩むな
そんなことで文句を言う会社なんてクソだから就職するな
66
名前:
デフォルトの名無しさん
:02/05/21 13:14
>>57
その通りみたいです。これでOKだと思う。
これでやっとoperator使える〜YO〜
/* 部分特殊化を使う operator== test*/
Test<CDialog,type_default> s1,s2;
s1.CmnTest();
if(s1 == s2){}
Test<CString,type_cstring> w1,w2;
w1.CmnTest();
if(w1 == w2){}
Test<CWnd,type_cwnd> o1,o2;
o1.CmnTest();
if(o1 == o2){}
/*この下はヘッダー*/
enum TypeM{
type_default,type_cstring,type_cwnd
};
template<typename T,TypeM type> class Test :public T
{
public:
friend bool operator ==(const Test<T,type>& t1,const Test<T,type>& t2);
void CmnTest() const
{AfxMessageBox("Default--CmnTest()");}
};
template<> class Test<CString,type_cstring> :public CString
{
public:
friend bool operator ==(const Test<T,type_cstring>& t1,const Test<T,type_cstring>& t2);
void CmnTest() const
{AfxMessageBox("CString--CmnTest()");}
};
template<> class Test<CWnd,type_cwnd> :public CWnd
{
public:
friend bool operator ==(const Test<T,type_cwnd>& t1,const Test<T,type_cwnd>& t2);
void CmnTest() const
{AfxMessageBox("CWnd--CmnTest()");}
};
template <typename T,TypeM type> bool operator ==(const Test<T,type>& t1,const Test<T,type>& t2)
{
//typeは定数なので最適化時にswitchステートメントからは1つの関数が得られる。
//これがtemplateの最も優れた性質なのです。(MSDN参照)
switch(type)
{
case(type_cstring):
AfxMessageBox("CString--operator==");
break;
case(type_cwnd):
AfxMessageBox("CWnd--operator==");
break;
default:
AfxMessageBox("Default--operator==");
break;
}
return true;
}
67
名前:
58=64
:02/05/21 13:19
>>65
むはー、心強いお言葉!
いえ正直に言うと、できればコーディングスタイルは
変えたくないなぁ…といった所が本音でして…。
ただネット上で、あまりに前者型をみかけないので、ひょっとして全滅
しちゃったのかなと。また就職先がクソ会社かもしれないですしねぇ(´Д⊂
59+65さんのお言葉を胸に、少し模索しつつも当面この
スタイルでいこうと思います。レスありがとうございました。
68
名前:
なぜ?
:02/05/21 17:02
>>53
,56,62,63さん
理解できました。ありがとうございました。
cin >> iで読み込みに成功するとは、cinストリームからデータがiに移ってcinからは
取り除かれる。
cin >> iで読み込みに失敗するとは、cinからデータがiに移らずcinに残ったまま
になる。ということなんですね。読み込みの成功とか失敗の意味が分かってませんでした。
69
名前:
_
:02/05/21 18:46
仮想関数って遅いって言われてるけど実際どうなんですか?
最近のハードウェアなら問題ないような気がするのですが・・・
70
名前:
デフォルトの名無しさん
:02/05/21 18:52
>>69
仮想関数が遅いっていうなら、関数のポインタを通してのコールも
遅くなるよ。実際はCALL時のオーバーヘッドが元々大きいので、そんなに
変わらないと思われ。
71
名前:
_
:02/05/21 18:56
>>70
そうですか。今作ってるソフト全部仮想関数にして実行してみたんですが全然変わらなかったので。。。
1ステップだ3ステップだと言ってる時代はもう終わったのかな。
72
名前:
デフォルトの名無しさん
:02/05/21 19:04
メモリ参照の分だけペナルティがある。
極限まで最適化する際には足かせになる。
ただ、仮想関数でも呼び出すメソッドが自明な場合は
メモリを介さずに直接callされる
73
名前:
デフォルトの名無しさん
:02/05/21 19:13
>>71
そうですねえ。STLなんて使ってみたらわかるけど、糞みたいにステップ
数を消費しますよ。あまりステップ数にこだわならない方がいいかも・・・
デストラクタは一回も継承しなくても、仮想関数として定義することを勧めて
いる本もあるぐらいですからねえ。
74
名前:
_
:02/05/21 19:14
>>72
なるほど、直接呼ばれてたのかも。。。テストプログラム作ってみます。thx
75
名前:
_
:02/05/21 19:22
>>73
それでもSTL便利すぎですよね><
ちょっとwebで調べたところdynamic_cast仮想関数でも100万回実行して0.23秒?って・・・
コストに拘るスーパーハカー目指すの萎えます・・・
76
名前:
_
:02/05/21 19:41
class A { bool b; void Func(); };
class B : public A { virtual void Func(); };
void A::Func() { b = false; }
void B::Func() { b = true; }
10000*10000回実行したところvirtual使っても使わなくても両方7か8秒でした。
最近だとステップ数で考えるよりキャッシュにヒットしやすいように書いた方がいいのかな。
77
名前:
デフォルトの名無しさん
:02/05/21 19:56
クラスの初期化リストで配列を初期化することは出来るのでしょうか?
教えてください。
78
名前:
デフォルトの名無しさん
:02/05/21 19:59
>>77
できません
79
名前:
デフォルトの名無しさん
:02/05/21 20:12
わかりました。
それでは、クラスに定数の配列とかを置くことはできないのですか?
80
名前:
デフォルトの名無しさん
:02/05/21 20:18
static constなら出来ないこともないけど
81
名前:
デフォルトの名無しさん
:02/05/21 20:28
>>78
,80
ありがとうです。
82
名前:
デフォルトの名無しさん
:02/05/21 22:04
C++builder買おうとおもってるんですが、
ProfessionalとPersonalってそんなに違うんですか?
83
名前:
デフォルトの名無しさん
:02/05/21 22:33
template<
class T1,
template<class>class CP1
>class RRR{};
このtemplateは何も意味しているんですか?VCしか使ったこと無いから
わかんないよ。
84
名前:
デフォルトの名無しさん
:02/05/21 22:54
>>83
RRR<int, vector> とかそんな風に書けたりする意味。
85
名前:
デフォルトの名無しさん
:02/05/21 23:05
>>84
template<typename A,typename B>class AAA{};
と何が違うの??
86
名前:
デフォルトの名無しさん
:02/05/21 23:14
>>85
マクロと同じ。
マクロ定義の中に先に定義されたマクロがあるだけ。
87
名前:
デフォルトの名無しさん
:02/05/21 23:21
>>85
それだと AAA<int,vector> でなくて AAA<int, vector<int> > とかになる。
88
名前:
83
:02/05/21 23:21
>>84
>>86
サンクス♪
89
名前:
デフォルトの名無しさん
:02/05/21 23:56
>>86
それはちと違う。その例でいうなら、先に定義したマクロを引数として
取ることができるマクロ、という言い方になる。
あるいは関数ポインタを引数にとる関数、というアナロジーのほうが
適切かと。
90
名前:
デフォルトの名無しさん
:02/05/22 03:04
● C++とCの(自作)ライブラリを併用した時の質問です。
==== sub.h =================================
void sub(const char *);
==== sub.c =================================
#include <stdio.h>
#include "sub.h"
void sub(const char *s)
{
printf("%s\n",s);
}
==== main.cc ===============================
#include "sub.h"
int main(int argc, char *argv[])
{
sub("itteyoshi");
}
==== compile ==============================
g++ -Wall -g -c main.cc
gcc -Wall -g -c sub.c
g++ -Wall -g main.o sub.o -o main
main.cc:4: undefined reference to `sub(char const *)'
collect2: ld returned 1 exit status
Cだったら問題なくリンクできるのに〜? なぜ〜? 名前空間の問題
だと思うんですけど・・・using namespace std;でもダメでした・・・
91
名前:
デフォルトの名無しさん
:02/05/22 03:07
>>90
ねえ、標準ヘッダのひとつくらい覗いてどう書いてあるか見てみようよ。
92
名前:
90
:02/05/22 03:18
>>91
即レスサンクスコ
……sub.hにexternがないとか??
・Cだとあってもなくてもコンパイル通る
・C++だとあってもなくてもコンパイル通る
んですが……。
もしかして凄く恥ずかしい間違いしているような気がしてきた……
でもわからん……
93
名前:
デフォルトの名無しさん
:02/05/22 03:49
#ifdef __cplusplus__
extern "C" {
#endif
void sub(const char*);
#ifdef __cplusplus__
}
#endif
たしか、こんな感じ
94
名前:
デフォルトの名無しさん
:02/05/22 05:26
ワイルドカードのパターンマッチのソースが載っている場所又は
自分でつくれる方教えてください。
入力:パターン文字列(*abc*,?abcなど)、調べる文字列(ababcd)
出力:マッチしたかどうか
似たようなソースでも結構です。お願いします。
95
名前:
デフォルトの名無しさん
:02/05/22 05:33
GNU RE
96
名前:
デフォルトの名無しさん
:02/05/22 05:55
>>94
http://pc.2ch.net/test/read.cgi/tech/1021459016/623-668
97
名前:
デフォルトの名無しさん
:02/05/22 08:16
JavaScriptに値を渡すことってできますか?
98
名前:
デフォルトの名無しさん
:02/05/22 08:47
C++ からブラウザの JavaScript へ?
無理。Java でも使え。
99
名前:
97
:02/05/22 09:57
>>98
サンクスです。
100
名前:
デフォルトの名無しさん
:02/05/22 10:04
100
101
名前:
90
:02/05/22 10:09
>>93
Thx。うまくいきました。
ちなみに__cplusplus__ではなく、__cplusplusでした
102
名前:
デフォルトの名無しさん
:02/05/22 12:02
c_pointer = new char[1];
こんな風に、要素が一つでも
delete[] c_pointer;
にしなきゃだめですよね?
delete c_pointer;
じゃまずいっすよね?
103
名前:
デフォルトの名無しさん
:02/05/22 12:54
dame
104
名前:
デフォルトの名無しさん
:02/05/22 13:32
なんか質問が違った・・
こっちでおながいします
c_pointer = new char[1];
こういう一つだけの確保でも
delete[] c_pointer;
しちゃってもOKですよね?
105
名前:
デフォルトの名無しさん
:02/05/22 13:51
そうしなきゃだめ
106
名前:
デフォルトの名無しさん
:02/05/22 14:12
はい、わかりました(^▽^)/
サンクス!
107
名前:
デフォルトの名無しさん
:02/05/22 15:09
>>102
単一のnewと配列のnewでは、ヒープ領域に確保のされる方法が違うのよん。
配列のnewはオブジェクトの数も覚えているのよん。
なんで二種類もnewがあるかと言うとねん、少しでもメモリを節約するためなの
よん。
108
名前:
デフォルトの名無しさん
:02/05/23 02:21
VC6,VC7では内部的に同じだったりするからまたややこしい
109
名前:
デフォルトの名無しさん
:02/05/23 03:49
ややこしいって・・・
内部的には同じでも、同じという保証があるワケじゃないから絶対にやっちゃダメ
110
名前:
デフォルトの名無しさん
:02/05/23 03:51
もちろんやんないけど
デバッガ等で追ってもエラーになんないんだな
他のコンパイラ(g++とか)とソース共有してると死ねる
つか死んだ
111
名前:
デフォルトの名無しさん
:02/05/23 04:14
やらないんじゃ何で死ぬんだよ
112
名前:
デフォルトの名無しさん
:02/05/23 07:21
デストラクタの呼ばれ方に明確に差があると思うが。
メモリ領域の開放自体はまぁ問題ないにせよ。
113
名前:
デフォルトの名無しさん
:02/05/23 14:14
文字列を好きな位置に挿入できる可変長な文字列クラスってもうどっかにありますか?
114
名前:
デフォルトの名無しさん
:02/05/23 14:15
>>113
それくらい自分でつくれよ。
挿入したい文字列の長さ分、挿入位置より後の文字列をmemmoveすればいいだけだろ。
115
名前:
114
:02/05/23 14:16
ん?自分でつくって公開したいってことか?
116
名前:
デフォルトの名無しさん
:02/05/23 14:19
>>113
標準に存在します
117
名前:
113
:02/05/23 14:24
ガ━(TДT)━ン!
もうあるのか・・・
作っても意味なかった
118
名前:
デフォルトの名無しさん
:02/05/23 14:28
可変長文字列クラスなんてダレでもよく使うくらすじゃん
無い方がどうかしてる
119
名前:
デフォルトの名無しさん
:02/05/23 14:42
でも、標準のstringっていまいちだよね。
Perl感覚で扱えるよう、自分でsplitや部分文字列の一括変換機能
も使える文字列クラス作ったよ。あ、でもinsertは入れ忘れてたな。
今度入れておこう。
120
名前:
デフォルトの名無しさん
:02/05/23 14:51
再発名君登場。boost使えばいいやん。
文字列は文字列、勝手に分裂したりすると言うオブジェクトのとらえ方は可笑しい
121
名前:
デフォルトの名無しさん
:02/05/23 14:57
http://www.openwatcom.com/
ソースキタ━━(゚∀゚)━━━ !!!!
122
名前:
119
:02/05/23 15:00
>>120
splitは分裂というより、文字列配列の生成だな。
処理を行う文字列自体は、Perl同様に当然不変。
str.split("abc");
とやると"abc"をキーに文字列を分割し、分割した文字列の配列を
新たに生成して返す感じ。
あと、再発明もなかなか楽しいものだよ。
特に文字列処理は、アルゴリズムの習得や実験にも最適だからね。
123
名前:
デフォルトの名無しさん
:02/05/23 15:07
そんな超基礎的な再発名をしても楽しくない罠
124
名前:
デフォルトの名無しさん
:02/05/23 20:30
http://www.kumei.ne.jp/c_lang/cpp/cpp_29.htm
のkclass.h
ってやつがコンパイルできないんですけど。初心者逝ってよしですか?
125
名前:
デフォルトの名無しさん
:02/05/23 20:35
うーん。単独ではコンパイルできないのか。
126
名前:
デフォルトの名無しさん
:02/05/23 23:05
練習するのもいいが、文字列のコピー延々と作られてもなあ。
概念的にはそれでもいいけど、内部には元文字列と、
ポインタかインデックスと長さの配列だけ持ってりゃ
いいんでない?
127
名前:
デフォルトの名無しさん
:02/05/23 23:33
以下のようなテストをしていて疑問に思ったのですが、
デストラクタにvirtualをつけると関数が失敗するみたいのですが、
なぜなのか理由が分かりません。
何か理由があるのでしょうか?
/*Test*/
CTest tt;
static_cast<CString&>(tt) = _T("testdesu");
tt.Format2(_T("%sです"),(tt));
AfxMessageBox(tt);
/*class*/
class CTest :public CString
{
public:
inline void Format2(const TCHAR* lpszFormat, ...)
{
va_list argList;
va_start(argList, lpszFormat);
CmnFormatV(lpszFormat, argList);//call CmnFormatV
va_end(argList);
}
inline void CmnFormat2( const TCHAR* lpszFormat, va_list args )
{this->FormatV(lpszFormat,args);}
CTest()
{};
//デストラクタ
//virtual ~CTest()
~CTest()
{};
};
128
名前:
デフォルトの名無しさん
:02/05/23 23:36
×inline void CmnFormat2( const TCHAR* lpszFormat, va_list args )
inline void CmnFormatV( const TCHAR* lpszFormat, va_list args )
129
名前:
デフォルトの名無しさん
:02/05/23 23:38
>>128
何々?再帰呼び出しするって事?
130
名前:
デフォルトの名無しさん
:02/05/23 23:43
もともとのCStringのデストラクタがvirtualでないからでわ?
131
名前:
デフォルトの名無しさん
:02/05/23 23:47
>>130
それに一票。だいたいpublic派生したら、virtualキーワードはつける必要ないよ。
親のを継承する。
132
名前:
127
:02/05/23 23:49
>>129
CStringの派生クラスにCString::Formatの関数と同じものを
を書いてそれを呼んでるのですが、
デストラクタを virtual宣言すると、失敗してるみたいなんです。
デバックしても手がかりがつかめないので聞いてみようと思いました。
どういうときにvirtual宣言をしてはいけないのでしょうか?
133
名前:
デフォルトの名無しさん
:02/05/23 23:54
>>132
親のCStringクラスのデストラクタがvirtual宣言されてないと、継承先のクラス
でもvirtual宣言してはいけない。
134
名前:
誰か
:02/05/23 23:56
あの、ちょっと質問があるんですがド忘れしてしまったので
思い出したら書きますんでよろしくお願いしますm(..)m
135
名前:
デフォルトの名無しさん
:02/05/24 00:02
m( 。 。)m ぃ ゃ
136
名前:
デフォルトの名無しさん
:02/05/24 00:03
ゃ-ょ
137
名前:
デフォルトの名無しさん
:02/05/24 00:04
>>132
というか、継承したのなら、virtual宣言をつけたらいいかどうか悩む必要は
ないです。書かなければいい。親と同じになるから。
もし必ずvirtualを書かなければいけないとしたら、いちいち親のヘッダー
ファイルを開いて読まなければならないことになるよ。
138
名前:
デフォルトの名無しさん
:02/05/24 00:05
ぃゃょぃゃょ モ スキノウチ
139
名前:
デフォルトの名無しさん
:02/05/24 00:05
(._.;) そんなこと言わないでくださいよ・・
140
名前:
127
:02/05/24 00:06
デストラクタをvirtualにするということは
親と子のデストラクタ名が違うけど
デストラクタはオバーライドされてしまうということなのでしょうか?
141
名前:
デフォルトの名無しさん
:02/05/24 00:11
>>140
デストラクタはクラス名と同じだから、厳密にはオーバーライドではありません。
仮想関数として宣言されていれば、自分を呼び出してから親のデストラクタも
呼び出しに行きます。仮想関数でなければ、自分しか呼び出しません。
142
名前:
デフォルトの名無しさん
:02/05/24 00:15
>>140
「仮想デストラクタ」で調べておくといいかも
143
名前:
デフォルトの名無しさん
:02/05/24 00:17
>>141
そりゃ違う。仮想関数のデストラクタでも、そうでなくても、
親は呼びにいくぞ。
仮想関数として宣言されているメリットは、基底ポインタが
派生クラスを指していても、正しいデストラクタが呼ばれるよ
うにするため。
144
名前:
デフォルトの名無しさん
:02/05/24 00:21
>>141
「厳密には」って・・・、大雑把にゆってもオーバーロードじゃぁないでしょ。
しかも理由が「デストラクタはクラス名と同じだから」って・・・・、意味わからん。
145
名前:
デフォルトの名無しさん
:02/05/24 00:22
結論。
・仮想デストラクタは
146
名前:
デフォルトの名無しさん
:02/05/24 00:24
2人とも仮想デストラクタを調べなはれ
147
名前:
デフォルトの名無しさん
:02/05/24 00:32
下のプログラムで、~A()のvirtualを取ったものと出力結果をよく比べて
みれば仮想デストラクタの存在理由が理解できます。
#include <iostream>
using namespace std;
class A {
public:
virtual ~A() { cout << "~A()" << endl; }
};
class B : public A {
public:
~B() { cout << "~B()" << endl; }
};
int main()
{
A* a = new B;
delete a;
}
148
名前:
127
:02/05/24 00:53
かぶるけど一応全通り試してみた。
結論としては
デストラクタがvirtual宣言されていない現在のクラスでは
newで作成したオブジェクトのデストラクタが呼ばれない。
//CT<CBase> n_n;//2
//CT<CBaseV> n_v;//2
//CTV<CBase> v_n;//2
//CTV<CBaseV> v_v;//2
//CBase *pn_n = new CT<CBase>;//~CBase Only
//delete pn_n;
//CBaseV *pn_v = new CT<CBaseV>;//2
//delete pn_v;
//CBase *pv_n = new CTV<CBase>;//~CBase Only
//delete pv_n;
//CBaseV *pv_v = new CTV<CBaseV>;//2
//delete pv_v;
struct CBase
{
CBase(){}
~CBase()
{
AfxMessageBox(_T("~CBase()"));
}
};
struct CBaseV
{
CBaseV(){}
virtual ~CBaseV()
{
AfxMessageBox(_T("~CBaseV()"));
}
};
template<typename T> struct CT :public T
{
CT()
{}
~CT()
{
AfxMessageBox(_T("~CT()"));
}
};
template<typename T> struct CTV :public T
{
CTV()
{}
virtual ~CTV()
{
AfxMessageBox(_T("~CTV()"));
}
};
149
名前:
127
:02/05/24 00:58
見間違えてました。
×デストラクタがvirtual宣言されていない現在のクラスでは
newで作成したオブジェクトのデストラクタが呼ばれない。
○継承元のデストラクタがvirtual宣言されていないと
継承先のオブジェクトをnewで作成したときに
継承先のデストラクタが呼べない。
150
名前:
デフォルトの名無しさん
:02/05/24 00:58
>>148
結論は、CStringを継承する時は、デストラクタにvirtualを付けてはいけない
という事と、new/deleteせずに静的にオブジェクトを扱うように注意しなけれ
ばならないという事になりそうですね。
151
名前:
デフォルトの名無しさん
:02/05/24 01:08
>>150
148のケースのデストラクタが呼べてないということは
C++の言語仕様上では
メモリ上にオブジェクトの一部が残るのでしょうか?
それともただデストラクタの処理ができないのでしょうか?
それとも未定義?
152
名前:
127
:02/05/24 01:16
とりあえず問題点と解決策が150で明確になったので、
そのスタイルでいこうと思います。
ありがとうございました。>ALL
153
名前:
デフォルトの名無しさん
:02/05/24 01:19
PCの時間テスト
154
名前:
デフォルトの名無しさん
:02/05/24 01:20
>>151
デストラクタとdeleteの本体は全く別物ですから、deleteは正しく行われます。
しかし、オブジェクトの中で新たに領域を動的に確保していた場合などは、
その領域は残ってしまいます。
例えば下の例ですと、int* pの指す領域が開放されずに残ります。
class A {
int a;
};
class B : public A {
int* p;
public:
B() { p = new int; }
~B { delete p; }
}
int main()
{
A* a = new B;
delete a;
}
155
名前:
デフォルトの名無しさん
:02/05/24 01:21
>>154
訂正
×~B
○~B()
156
名前:
151
:02/05/24 01:46
>>154
なるほど、ということは動的オブジェクトさえ使わなければ
安全であるということですね。
これで安心して寝られます。ありがとうございました。
157
名前:
デフォルトの名無しさん
:02/05/24 01:48
dynamic depend
158
名前:
デフォルトの名無しさん
:02/05/24 03:45
>>127
> tt.Format2(_T("%sです"),(tt));
可変長引数だからoperator LPCTSTR()が呼ばれてない罠。
確か仮想関数が1つもないとそれでも動いたはず。
159
名前:
デフォルトの名無しさん
:02/05/24 05:40
あるクラスのサブクラスがデストラクタをvirtualにする意味はある。
たとえば、デストラクタがvirtualでないstd::basic_string<>を継承したクラス
template<T>
class specialized_string : public std::basic_string<T, original_traits<T>, allocator<T> >
{
public:
virtual specialized_stirng() { }
};
コイツを絶対にこれより上(basic_string)にキャストせず、
specialized_stringまでしかキャストしないなら、
このクラスのサブクラスのすべてのデストラクタが呼ばれる事が保証される。
この場合、コンポジションを使った方が適切ではあるけど。
boostのnoncopyableを見るまでダメだと信じていた
160
名前:
デフォルトの名無しさん
:02/05/24 11:43
>>158
明示的なキャストしている場合はちゃんと動くんですよね。
<stdarg.h>の _ADDRESSOF(v)の値が
仮想関数を含んでいるときに違う値を指してるみたい。
可変数引数マクロと仮想関数の相性が悪いのか...。
161
名前:
158
:02/05/24 12:09
>>160
#include <stdio.h>
class A {
public:
A(const char *a) : buf(a) { }
~A() {}
const char *buf;
};
class B {
public:
B(const char *a) : buf(a) { }
virtual ~B() {}
const char *buf;
};
int main() {
A a("test"); B b("test");
printf("offsetof(A::buf) == %08X\noffsetof(B::buf) == %08X\n", (char *)&a.buf-(char *)&a, (char *)&b.buf-(char *)&b);
return 0;
}
これでわかるかもしれづ。
ヒントはvtable。
162
名前:
158
:02/05/24 12:18
書き忘れ。
>>160
> 可変数引数マクロと仮想関数の相性が悪いのか...。
仮想関数がない場合は、「たまたま」動いてただけ。
CStringの場合は、それを期待して実装された可能性が高いが。
163
名前:
デフォルトの名無しさん
:02/05/24 12:46
>>162
ということは、CString の先頭のメンバが _T buf[] になってるってこと?
ちょっとイヤな実装だな。
164
名前:
158
:02/05/24 13:04
>>162
いや、CStringのメンバ変数は格納してる文字列へのポインタだけ。
sizeof(CString) == 4。
で、CStringを値渡しすると文字列へのポインタがスタックに積まれることになる。
# うーん、うまく説明できないな…。
165
名前:
デフォルトの名無しさん
:02/05/24 13:20
>>164
あ、了解。値渡しになるわけか。参照渡しと勘違いしてたよ。
166
名前:
デフォルトの名無しさん
:02/05/24 13:45
fstreamのget関数って一バイトしか読まないですよね?
そうじゃなくて、日本語の一文字を読めるようにしたんですが、
どうしたらいいですか?
167
名前:
166
:02/05/24 13:45
間違えました。
×したんですが
○したいのですが
168
名前:
デフォルトの名無しさん
:02/05/24 13:46
自力でがんばれ
169
名前:
166
:02/05/24 13:49
>>168
自力というのは、文字コードを調べて判定するってことですか?
170
名前:
デフォルトの名無しさん
:02/05/24 13:51
>>169
その通り。AdapterPatternあたりで実装するのも悪くないだろう
171
名前:
デフォルトの名無しさん
:02/05/24 13:58
wfstream使え。
172
名前:
デフォルトの名無しさん
:02/05/24 14:00
高々
>>166
程度のためにwide対応まですることはないだろ
173
名前:
デフォルトの名無しさん
:02/05/24 14:01
>>172
でも、便利だったりする。
174
名前:
166
:02/05/24 14:02
>>170
ふーむ。そうですか。Adapterはちょっと忘れてるのでデザパタ
本でも見て検討してみます。
>>171
wcharだと普通コードはUnicodeになりますよね?
UNIXなので、EUCとかでやりたいんですが。
wfstreamでこのEUCは扱えますか?
char_traitsとか使うんですかね?
175
名前:
166
:02/05/24 14:14
どうやらgoogleで調べたらlocaleをセットするらしい
ですね。
だいたいわかってきました。どうもありがとうございました。
176
名前:
ヘルプ!
:02/05/24 14:26
1.単語入力
2.文章入力
3.2の文章に1の単語がいくつはいってるか報告
どなたかこのプロフラミングしてください!ほんとお願いします。
C++
177
名前:
デフォルトの名無しさん
:02/05/24 14:30
>>176
>プロフラミングしてください!
ここにそれを行える技術者は一人もいないと思われ。
178
名前:
デフォルトの名無しさん
:02/05/24 14:32
>>176
文字列の入力方法は知っているか?
入力される単語は1つか、複数か?
入力される文章は1つか、複数か?
どうせ宿題の期限が近づいたんだと思うが。
179
名前:
ヘルプ!
:02/05/24 14:35
>>178
そうなんです!課題提出しなきゃいけないんです!
>入力される単語は1つか、複数か?
単語はひとつです!
>入力される文章は1つか、複数か?
これもひとつです!
どうかお願いします!
180
名前:
デフォルトの名無しさん
:02/05/24 14:40
string str, sentence;
cin >> str;
cin >> sentence;
string::size_type n = 0, i = 0;
while((i = sentence.find(str, i + 1)) != string::npos)
n++;
181
名前:
デフォルトの名無しさん
:02/05/24 14:41
>>180
やっぱり俺はC++が生理的に受け付けない。
う〜む。
182
名前:
デフォルトの名無しさん
:02/05/24 14:46
cin>>str
じゃ余計なところで区切られるか。
getline(cin, str);
getline(cin, sentence);
で。
183
名前:
ヘルプ!
:02/05/24 14:50
まじ感謝!ほんとありがとうございます!ではのちほど。
184
名前:
デフォルトの名無しさん
:02/05/24 14:51
宿題スレに逝って下さい。
http://pc.2ch.net/test/read.cgi/tech/1020785918/
185
名前:
デフォルトの名無しさん
:02/05/24 14:59
>>184
終わってからレスするな
余計なレスが一つ増える
186
名前:
デフォルトの名無しさん
:02/05/24 15:20
>>185
これも無駄レスだと思う罠。
187
名前:
デフォルトの名無しさん
:02/05/24 16:31
>>158
追加の試験もしてみました。162,163の言われている通りの気がしてきました。
自クラスをバッファの型にキャストしないでも可変数引数が動くようにしてる。
ただその代償に仮想関数が使えなくなってるのか。
可変数引数マクロは型が固定でないので
(キャスト演算子を定義しても)型の整合性による暗黙の型変換が起こらない。
==127が動かなかった
#include <stdio.h>
#include <stdarg.h>
struct A {explicit A(const char *a) : buf(a) {}
~A() {}
const char *buf;};
struct B {explicit B(const char *a) : buf(a) { }
virtual ~B() {}
const char *buf;};
template<typename T> struct CT :public T{
CT(const char *a)
:T(a){}
~CT() {}
operator const char*() const{return (static_cast<const T&>(*this)).buf;}
};
template<typename T> struct CTV :public T{
CTV(const char *a)
:T(a){}
virtual ~CTV() {}
operator const char*() const{return (static_cast<const T&>(*this)).buf;}
};
int main() {
A a("test"); B b("test");printf("offsetof(A::buf) == %08X\noffsetof(B::buf) == %08X\n", (char *)&a.buf-(char *)&a, (char *)&b.buf-(char *)&b);
CT<A> nn("Test");const char *c_nn = (const char*)(nn);
CTV<A> nv("Test");const char *c_nv = (const char*)(nv);
CT<B> vn("Test");const char *c_vn = (const char*)(vn);
CTV<B> vv("Test");const char *c_vv = (const char*)(vv);
//N-N
printf("(N-N): offsetof(A::buf) == %08X \n", (char *)&nn.buf-(char *)&nn);
printf("(N-N): sizeof(nn) %d \n", sizeof(nn));
printf("(N-N): _ADDRESSOF((const char*)(nn)) - _ADDRESSOF(nn) == %d \n",_ADDRESSOF(c_nn) - _ADDRESSOF(nn));
printf("(N-N): _SLOTSIZEOF((const char*)(nn)) - _SLOTSIZEOF(nn) == %d \n",_SLOTSIZEOF(c_nn) - _SLOTSIZEOF(nn));
//N-V
printf("(N-V): offsetof(A::buf) == %08X \n", (char *)&nv.buf-(char *)&nv);
printf("(N-V): sizeof(nv) %d \n", sizeof(nv));
printf("(N-V): _ADDRESSOF((const char*)(nv)) - _ADDRESSOF(nv) == %d \n",_ADDRESSOF(c_nv) - _ADDRESSOF(nv));
printf("(N-V): _SLOTSIZEOF((const char*)(nv)) - _SLOTSIZEOF(nv) == %d \n",_SLOTSIZEOF(c_nv) - _SLOTSIZEOF(nv));
//V-N
printf("(V-N): offsetof(B::buf) == %08X \n", (char *)&vn.buf-(char *)&vn);
printf("(V-N): sizeof(vn) %d \n", sizeof(vn));
printf("(V-N): _ADDRESSOF((const char*)(vn)) - _ADDRESSOF(vn) == %d \n",_ADDRESSOF(c_vn) - _ADDRESSOF(vn));
printf("(V-N): _SLOTSIZEOF((const char*)(vn)) - _SLOTSIZEOF(vn) == %d \n",_SLOTSIZEOF(c_vn) - _SLOTSIZEOF(vn));
//V-V
printf("(V-V): offsetof(B::buf) == %08X \n", (char *)&vv.buf-(char *)&vv);
printf("(V-V): sizeof(vv) %d \n", sizeof(vv));
printf("(V-V): _ADDRESSOF((const char*)(vv)) - _ADDRESSOF(vv) == %d \n",_ADDRESSOF(c_vv) - _ADDRESSOF(vv));
printf("(V-V): _SLOTSIZEOF((const char*)(vv)) - _SLOTSIZEOF(vv) == %d \n",_SLOTSIZEOF(c_vv) - _SLOTSIZEOF(vv));
return 0;
}
188
名前:
デフォルトの名無しさん
:02/05/25 01:01
Alexsndrescあげ?
189
名前:
デフォルトの名無しさん
:02/05/25 02:48
>>188
ん?
190
名前:
よっし〜
:02/05/25 15:20
C++の抽象クラスが保持するvtableって、プログラム実行中に書き換える事ってできるんでしょうか?
自前で関数ポインタの中身を切り替えて処理すれば良いんだけど、
vtableが使えるんだったそっちの方がスマートかなぁって・・・そうでもないか?
191
名前:
デフォルトの名無しさん
:02/05/25 15:21
実装依存だから、コンパイラ間の互換性は無くなる
192
名前:
デフォルトの名無しさん
:02/05/25 16:06
>>190
何をやりたいのか、意味がわからん…。『vtableをプログラム実行中に書き換える』って、
それがまさにオーバーライドっちゅうもんじゃないの? 継承じゃ処理できないことなんか?
193
名前:
デフォルトの名無しさん
:02/05/25 16:09
オーバーライドは実行時に書き換えない
194
名前:
デフォルトの名無しさん
:02/05/25 16:24
Bridge Pattern 使え・・・ってそーゆーコトじゃないのか?
195
名前:
よっし〜
:02/05/25 18:15
結局関数ポインタで切り替える事にしました。
>>191
> 実装依存だから
そうかー。自分の知らない間に新仕様とか出てないかなーと思ったんだけど...
>>192
オーバーライドは継承クラス毎にポインタを持っているけど、
自分がやりたいのは、クラスはそのままで、状態遷移的に処理を分岐させたいのだ。
class MyClass {
virtual void Func(void) = 0;
void _FuncA(void){ putchar('A'); }
void _FuncB(void){ putchar('B'); }
void _FuncC(void){ putchar('C'); }
void ChgFunc(void);
};
void MyClass::ChgFunc(void)
{
this->Func = _FuncA;
Func();
this->Func = _FuncB;
Func();
this->Func = _FuncC;
Func();
}
<< 実行結果 >>
ABC
こんな感じ...純粋仮想関数なんでこのままだとインスタンスが作れないけど、概念だけ汲み取ってくれれば...
>>194
Bridge Patternか〜、今度調べてみます。
んでも、そんなに大げさにするつもりでもなかったんだけどね。
ところでデザインパターンの本て、実装例がJavaである事が多いですよねぇ。
C++で解説してる物って無いかな?
なけなしの小遣いはたいて買った本が、Eiffelとかいう訳わからん言語で記述されてて、大失敗でした。
196
名前:
デフォルトの名無しさん
:02/05/25 18:54
>>195
簡単すぎ
197
名前:
デフォルトの名無しさん
:02/05/25 18:58
もうEiffelすぎてチンコからマンコがでるぜ(w
198
名前:
195 じゃねーけど
:02/05/25 19:05
>>196
> 概念だけ汲み取ってくれれば...
日本語ぐらい、汲み取ってくれ。
199
名前:
デフォルトの名無しさん
:02/05/25 19:41
>>195
GoFはC++とSmalltalkだが?
200
名前:
デフォルトの名無しさん
:02/05/25 19:53
とりあえず、デザインパターンで言うならStateパターンが
一番しっくり来る話なんだろうけど…。
http://www11.u-page.so-net.ne.jp/tk9/ys_oota/mdp/State/index.htm
ひとつのクラスで収めるなら、こういう実装が一番か?
class Hoge {
typedef void (Hoge::*FUNC)(void);
FUNC func_;
public:
Hoge() : func_(FuncA) {}
void FuncA(void){ putchar('A'); func_=FuncB;}// 呼び出されたら状態遷移する。
void FuncB(void){ putchar('B'); func_=FuncC;}
void FuncC(void){ putchar('C'); func_=FuncA;}
void Call(void){
(*func_)();
}
};
もしくは、メンバ関数をテーブル化して、呼び出す関数の番号を
状態として持つか。
http://www1.odn.ne.jp/synsyr/prog_cpp0.html
スマン。『抽象クラスである』って部分はまるで考慮してない。
というか、この辺の話をすでに分かってて、『vtableでスマートに
いけんか?』ってことなのか。だったら力にはなれんわ。
201
名前:
200
:02/05/25 19:54
アフォだった。FuncA,FuncB,FuncCをpublicにしてどうする。こいつらはprivateやね。
202
名前:
デフォルトの名無しさん
:02/05/25 20:10
http://www.s34.co.jp/cpptechdoc/misc/smc/index.html
これわ?
203
名前:
sage
:02/05/25 22:38
Functor、operator()の有用性と使用例について
教えてください。Modern C++ Design 5章読みましたが
さっぱりわかりません。
204
名前:
デフォルトの名無しさん
:02/05/26 01:34
>>203
例えば、
struct Show {
void operator()(int i) const {
cout << i << ' ';
}
};
と定義しておいて、
vector<int> v;
......
for_each(v.begin(), v.end(), Show());
のように使える。
C++標準ライブラリのP136〜137に次のような項目があります。
1.関数オブジェクトはスマート関数である。
2.関数オブジェクトはそれぞれ型を持つ。
3.関数オブジェクトは、たいていは通常の関数より高速である。
205
名前:
デフォルトの名無しさん
:02/05/26 02:22
よっし〜はStateパターンを知らないに1000インクリメント。
206
名前:
デフォルトの名無しさん
:02/05/26 08:48
>>195
それだと、現在のFuncが何なのか常に把握しないといけないし、
スレッドセーフじゃない。
this->Func = _FuncA;
としているが、C++の場合、型チェックが一致しないとコンパイルもできない。
ということで
普通にメンバ関数ポインタ使ったほうが安全な気がする。
人工知能の実験とかだったらそれもありかもしれん。
メンバ関数ポインタは型チェックが厳しいのでtemplateと併用した方が吉。
207
名前:
マクロ逝ってよし
:02/05/26 10:42
namespace, class 内のメソッドとして min( ... ) などを
宣言しているのですが(よくやりますよね?)
某ライブラリと組み合わせるときそのライブラリのヘッダで
#define min(...) とマクロ宣言されちゃってました。
それでウチのクラスなどの宣言 min(... がすべて置換されてぐちゃぐちゃになり
パースエラーが出まくって困っています。
こんなときどうしたら良いでしょうか?
マクロ置換はネームスペースも無視しまうのでしょうか?
208
名前:
デフォルトの名無しさん
:02/05/26 10:44
>>207
そりゃそうでしょ。マクロ置換はC++の文法無視だから。
209
名前:
デフォルトの名無しさん
:02/05/26 10:44
>>207
C++で#define使ってる某ライブラリとやらが悪い。
210
名前:
デフォルトの名無しさん
:02/05/26 10:51
#ifdef min
#undef min
#endif
を自前の min 宣言の前につっこんどけ。
211
名前:
デフォルトの名無しさん
:02/05/26 10:59
>>210
#undef min
の一行で十分でわ?
212
名前:
デフォルトの名無しさん
:02/05/26 11:00
自分がライブラリ作成者の立場で、マクロ使わんと不便だなーってときは、
どうすべきかね?(テンプレートでもinline関数でも代用できないとして)
#define __min(...) ってふうに、アンダーバー付けとくべき?
213
名前:
デフォルトの名無しさん
:02/05/26 11:05
>>212
>テンプレートでもinline関数でも代用できないとして
例えば?
214
名前:
212
:02/05/26 11:15
>>213
『例えば?』って聞くって事は、『そんなことは具体例が出るまでは考える必要はない』ってこと?
/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
| 実際に切羽つまるまで、ほったらかしにする、と…
\
 ̄ ̄ ̄|/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
∧_∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
( ・∀・) ∧ ∧ < ソンナコト言ってないでしょ!!
( ⊃ ) (゚Д゚;) \____________
 ̄ ̄ ̄ ̄ ̄ (つ_つ____
 ̄ ̄ ̄日∇ ̄\|ThinkPad|\
 ̄ ========= \
215
名前:
デフォルトの名無しさん
:02/05/26 11:27
>>213
代用できないマクロの具体例は、Modern C++ Design 57ページ、『タイプリスト生成の単純化』でどうよ?
216
名前:
デフォルトの名無しさん
:02/05/26 11:49
>>212
頭にアンダースコアを付けるのはまずいっしょ。オレなら MYLIB_MIN とか、
とにかく他とはバッティングせず、一目でマクロとわかる名前を付けるな。
217
名前:
デフォルトの名無しさん
:02/05/26 11:52
WinならGUID生成させて頭につける。ほぼ衝突しない。
218
名前:
デフォルトの名無しさん
:02/05/26 12:10
>>212
全部大文字で書け。
219
名前:
デフォルトの名無しさん
:02/05/26 12:17
テンプレート引数で何かのポインタ型を使ってるとき、それに NULL を
渡せないという仕様になっているのはなぜ? たとえば
template< char *Ptr> class Hoge { … };
があったとき、Hoge< NULL > はコンパイルできないんですが。
220
名前:
デフォルトの名無しさん
:02/05/26 12:28
>>217
でも、そんなマクロは使いたくない。
221
名前:
デフォルトの名無しさん
:02/05/26 12:28
>>219
NULLの型がchar*として定義される実装ならそれで通るんじゃないの?
もし
#define NULL 0
とかだったら template<int> Hoge ... が無いから、そりゃ当然エラー。
222
名前:
デフォルトの名無しさん
:02/05/26 12:34
>>219
なぜなら NULL は 0 に置換されて、0 は int なので。
なぜ暗黙にヌルポインタに変換されないのかは知らんけど。
Hoge<(char*)NULL> とすればコンパイル出来ます。
223
名前:
219
:02/05/26 12:38
>>221
Hoge<(char *)0> もコンパイルできないです
224
名前:
219
:02/05/26 12:41
>>222
あり? g++ 3.0.4 ではコンパイルできませんでした。
`0' is not a valid template argument
it must be the address of an object with external linkage
というようなエラーが出ます。
225
名前:
デフォルトの名無しさん
:02/05/26 12:47
C++Builder6はコンパイル出来ました。ちょい調べてみる。
226
名前:
221
:02/05/26 12:51
>>225
VC++ と Bcc では通った。ただし VCはHoge<NULL>でも通ってしまう。
DigitalMarsは内部コンパイラエラー。gcc は2.95でもダメだた。
つーか Hoge<"aaaa"> とかすらコンパイルエラーになると
思うんだけど、char*を取るtemplateってどうやって使うものなん?
227
名前:
デフォルトの名無しさん
:02/05/26 13:14
探し出した。これかな。
14.3.2 Template non-type arguments
1- A template-argument for a non-type, non-template template-parameter shall be one of:
以下略。
an integral constant-expression of integral or enumeration type に該当しそうな気もするんだけど、しないのかもしんない。ポインタは integral ではないのかな。ないのかも。
>>226
>つーか Hoge<"aaaa"> とかすらコンパイルエラーになると
それは、はっきり書いてある。
-2- A string literal is not an acceptable template-argument because a string literal is an object with internal linkage.
引用元 www.kuzbass.ru/docs/isocpp/template.html
228
名前:
デフォルトの名無しさん
:02/05/26 13:26
Ruby!!!!!!!!!!!!!!!1
なんでみんなRubyを貶すのかなー?
もしかして劣等感?僻んでる?
日本発の言語で世界に評価されているのはRubyしか存在しないんだから
みんなでRubyを盛り上げてC++やDelphiなんて、プププのプーってぐらいに
しなきゃ。
実際今まで10年ぐらいプログラミングしてきた俺だけど、Rubyより優れた
言語に出会った事がないよ。
やっぱり新しい言語は優れているんだろうね。
229
名前:
デフォルトの名無しさん
:02/05/26 13:40
>>228
>>やっぱり新しい言語は優れているんだろうね。
そんなあなたにはC#をお勧めします(藁
230
名前:
221
:02/05/26 13:41
>>227
そう、だから template<char*> って一体いかなる使い道があるのかと思って。
char c;
int main() {
Hoge<c> aaa;
...
}
なんてのは嫌ぞ。
231
名前:
221
:02/05/26 13:41
× Hoge<c> aaa;
○ Hoge<&c> aaa;
232
名前:
デフォルトの名無しさん
:02/05/26 13:43
char* p = "ABC";
Hoge<p> は通るみたい。
233
名前:
219
:02/05/26 14:09
>>232
g++ では通りませんでした。char p[] = "ABC"; なら通ります。
C++ の仕様的には、
>>224
に出てるエラーが言ってるように、
「外部リンケージを持つオブジェクトのアドレス」、つまり定数でなくては
なりません。
232 の p は変数なので、まあ通らないのは仕方がないかとも思うんですが、
定数である (char *)0 くらいはコンパイルできてもよいんじゃないかと。
元々は次のようなコードを書きたかったのです。
template<class X, const char *Name> class Hoge {
public:
void printName() {
if (Name) {
cout << Name << endl;
} else {
cout << typeid(X()).name() << endl;
}
}
};
234
名前:
よっし〜
:02/05/26 14:16
>> 205
Stateパターンぐらい知ってるなもし。
>> 206
> スレッドセーフじゃない
そうかー、仮想関数って全インスタンスで共通だもんね。なるほどなるほど。
> 現在のFuncが何なのか常に把握しないといけないし
「glBegin 〜 glEnd」のような感じで使うので、これに関してはそれでも良いのでした。
そうゆう意味では、「状態遷移」という表現は不適切だったカモ。
235
名前:
219
:02/05/26 14:32
とりあえず、とてもスマートとは言えないけど、
char dummy;
template<class X, const char *Name = &dummy> class Hoge {
public:
void printName() {
if (Name != &dummy) {
[以下略]
とやることで凌ぎました。
236
名前:
デフォルトの名無しさん
:02/05/26 14:49
>>233
それって、const char *Name は printNameの関数引数にしちゃいかんの?
なんでわざわざテンプレート引数にする?
237
名前:
デフォルトの名無しさん
:02/05/26 15:12
>>236
printName() 呼び出す度に、引数指定したくないからだろ。
適当なメンバ変数作っといて、インスタンス生成する時に指定すりゃ
いいと思う。
238
名前:
デフォルトの名無しさん
:02/05/26 17:24
C#っていうか.NET Framework SDK(VS.NETにあらず)の問題なのですが、
吐かれた.exeファイルをエクスプローラのプロパティで見たときに表示される
「バージョン情報」に情報を書き込むにはどうすればよいのでしょうか?
たぶんテキストのリソースを作るのでしょうけど、方法と書式が…。
「バージョン情報」タブを非表示にさせる方法もあれば、お願いします。
239
名前:
デフォルトの名無しさん
:02/05/26 17:26
死ぬほどスレ違い
氏ね
240
名前:
238
:02/05/26 17:26
うぇ〜ん、誤爆した〜。(泣
C#スレに書き直します…。
241
名前:
デフォルトの名無しさん
:02/05/26 18:24
>>221
> NULLの型がchar*として定義される実装ならそれで通るんじゃないの?
その実装は ANSI C++ に準拠してませんな。
242
名前:
デフォルトの名無しさん
:02/05/26 21:58
>>204
とても分かりやすい説明 ありがとうございました。
亀レススマソ
243
名前:
名無しさん
:02/05/27 10:57
初心者質問です。
class T
{
int n1;
int n2;
public:
T():n1(0),n2(0){}
T(int i,int j):n1(i),n2(j){}
};
なんていうクラス定義からオブジェクトを生成するとき
T obj; //デフォルトコンストラクタ
T obj(10,20); //引数付きコンストラクタ
としますが、以下の記述も文法上正しいのでしょうか?
T obj = T();
T obj = T(10,20);
244
名前:
デフォルトの名無しさん
:02/05/27 10:59
>>243
試せばいいものをわざわざ聞きに来るなよぅ。
基本的にはだめ。
でも
T2 obj=3;
とかは許容されてたりする。
T2(int)
扱い。
245
名前:
名無しさん
:02/05/27 11:00
if(cin >> i)のような記述で cin >> i の部分が暗黙のうちに
bool値に変換され、解釈される仕組みが分かりません。
どなたかご存知でしょうか?これって常識ですか?
246
名前:
デフォルトの名無しさん
:02/05/27 11:02
>>245
常識です(笑)
適当にC++の入門書開いてiostreamについての説明を読むがよろし
247
名前:
名無しさん
:02/05/27 11:08
>>244
どうもです。
ごもっともなんですが。。
実は、BCC5.5.1で試したところコンパイルできたので、
これも正しいのかなと思い、いろいろ本を見たのですが、
見つからなかったもので。文法上は駄目なんですね。
使わないことにします。
248
名前:
デフォルトの名無しさん
:02/05/27 11:09
>>245
cinには変換関数 bool() が定義されているんじゃない?
249
名前:
デフォルトの名無しさん
:02/05/27 11:10
>>247
class T
{
int n1;
int n2;
public:
T(int i = 0, int j = 0) : n1(i), n2(j){}
};
のようにすると簡単になります。この場合でも()と書くとエラーです。
250
名前:
デフォルトの名無しさん
:02/05/27 11:18
>>243-244
OKなのでは?
■過去ログ置き場に戻る■
1-
次250
最新50
DAT2HTML
0.33f Converted.