07/09/28 09:32:02
>>45
大差なくはない。vector使え。
例外安全な上に組込配列よりずっと便利だ。
51:デフォルトの名無しさん
07/09/28 10:11:22
2
4
16
256
65536
4294967296 * sizeof(double) = 8589934592b = 8192MB
52:デフォルトの名無しさん
07/09/28 10:15:48
そこまでいったら流石にメモリマップドファイル使う
53:37
07/09/28 10:45:46
>>47
「ウィンドウ作成データとして、CWinBase クラスの派生クラス CxxxWnd オブジェクトを指定することを忘れないで下さい。」
が、何を指しているのかわからないです。どこにCxxxWnd オブジェクトを指定するのでしょう?
54:37
07/09/28 10:50:39
WNDCLASSEXを登録するとき、サンプルではBaseWnd::WindowMapProcを指定
しろとあるけど、指定するものを自分自身のWinProcを指定してやり
Attachを呼べばいいのかな?
55:デフォルトの名無しさん
07/09/28 11:00:24
>>53
それは、CreateWindowExの最後の引数。
CxxxWnd wnd;
CreateWindowEx(..., &wnd);
こういう感じ。CreateWindow(Ex)の引数は
WM_CREATEまたはWM_NCCRAETEでCRATESTRUCTとして全て参照できる。
いつもこうしなければならないだから、
CreateWindowExもクラスのメンバにしてこの処理はしばしば隠蔽される。
そろそろスレ違いが近付いているぞ。
56:37
07/09/28 11:29:40
>>55
今そこ調べてました・・・
URLリンク(nomina.petit-archives.mydns.jp)
URLリンク(www7a.biglobe.ne.jp)
>>そろそろスレ違いが近付いているぞ。
もうすこし付き合ってください・・
その最後の引数に&wndを渡して自身のメンバ変数や関数にアクセス
する場合、が微妙です。
WM_CREATEで
LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam
というところはOKです。ここから自分のメンバにアクセスする方法が
いまいちです。
57:デフォルトの名無しさん
07/09/28 11:33:18
死ね
58:37
07/09/28 11:33:38
static Hoge3* pWnd = NULL;
pWnd = (Hoge3*)(((CREATESTRUCT*)lp)->lpCreateParams);
こんな感じか?な?
59:デフォルトの名無しさん
07/09/28 11:36:24
CxxxWnd *wnd = (CxxxWnd*)lpcs->lpCreateParams;
60:37
07/09/28 11:37:44
>>55
できますた。ありがとうございます!
あとは54なんですが・・・これがまた・・・orz
61:デフォルトの名無しさん
07/09/28 11:38:16
死ね
62:デフォルトの名無しさん
07/09/28 11:42:22
>>60
Win32API質問箱 Build57
スレリンク(tech板)
63:デフォルトの名無しさん
07/09/28 12:11:35
>>58
そこでstaticはやめとけ。
>>60
Hoge2::WinProcに相当するのが、44の指したページで言うCWndBase::WindowMapProc。
64:37
07/09/28 12:38:27
class Hoge:public CWndBase
public:
BOOL InitInstance( HINSTANCE hInstance );
private:
//オーバーライドしたWndProc
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
};
使うとき、
Hoge hoge;
hoge.InitInstance(hInstance);
InitInstanceの中ではウィンドウの登録、作成をする
WNDCLASSEX wcex;
:
wcex.lpfnWndProc = (WNDPROC)BaseWnd::WindowMapProc;//WndProc;
:
RegisterClassEx(&wcex);
で、CreateWindowする。最後の引数はthisを渡す。
こうすると、メッセージは、まずWindowMapProcで処理されて、
BaseWndのWndProcへ飛んできます。が、オーバーライドした自分のWndProcには飛んでこない
です。CreateWindow後のAttachとか呼んでみたのですが、変わらずです。
なんか、おしい気がするのですが、ぜんぜんですかね?
65:デフォルトの名無しさん
07/09/28 12:43:20
なぜ static が付いてる?
それでオーバーライドになってると思ってるのか?
66:デフォルトの名無しさん
07/09/28 12:48:32
>>64
44のページを良く見ろ。
WindowMapProcはstaticで、WndProcはvirtualだ。
静的メンバ関数で多態的なオーバーライドは不可能だ。
67:デフォルトの名無しさん
07/09/28 12:49:18
お前らの優しさに嫉妬
68:37
07/09/28 13:29:59
あ、static付いてる。コールバックはstatic付けることで解決、なんての
ばかり気にしてたので、普通につけちゃいました。
で、取ったらコンパイラ エラー C2555が出て、「そんなの聞いてませんが何か?」
とか思いつつ、調べること数分、どうにかメッセージを受信するとこまで
できたようです。
今は、慣れてないのにいろんなことやってしまった(気でいる)ので、
これから1つ1つ整理して、ちゃんとしたものを作っていきます。
みなさまありがとうございました。
69:デフォルトの名無しさん
07/09/28 14:22:21
やれやれ ┐(´ー`)┌
70:デフォルトの名無しさん
07/09/28 14:33:43
でさ、なんでこの話題がC++スレで?
71:デフォルトの名無しさん
07/09/28 15:26:42
相手する低脳がいるから
72:デフォルトの名無しさん
07/09/29 08:31:08
class A{
int a[10];
public:
}
73:デフォルトの名無しさん
07/09/29 08:34:44
途中で書いてしまいました失礼しました
class A{
int a[10];
public:
int *get_a(){return a;}
}
int main(){
int *p;
p = get_a();
for(int i = 0; i < 10; i++){
p[i] = ...
... = p[i];
}
return 0;
}
このようなコードってカプセル化を壊してますか?
74:デフォルトの名無しさん
07/09/29 08:40:45
>>73 うん。少し。
75:73
07/09/29 08:45:15
やはり配列のポインタを返すというのはまずいのでしょうか?
76:デフォルトの名無しさん
07/09/29 08:48:46
>>75 うん。少し。
77:デフォルトの名無しさん
07/09/29 10:23:23
>>78 うん。少し。
78:デフォルトの名無しさん
07/09/29 12:03:52
やはり>>77さんは早漏なのでしょうか?
79:デフォルトの名無しさん
07/09/29 12:37:28
早漏は経験をつめば治ります。めげずに頑張りましょう。
80:デフォルトの名無しさん
07/09/29 17:31:27
こんな感じにしちゃえば?
int get_a( int i ){return a[i];}
81:デフォルトの名無しさん
07/09/29 21:08:11
代入は?
82:デフォルトの名無しさん
07/09/29 21:12:06
>>81
int& get_a(int i) { return a[i]; }
int get_a(int i) const { return a[i]; }
83:デフォルトの名無しさん
07/09/29 21:22:13
effective C++読めよー。
84:デフォルトの名無しさん
07/09/29 21:44:16
っていうか言語以前の問題だろ。
っっていうか全部ネタだろ。
85:デフォルトの名無しさん
07/09/29 23:56:29
なんで誰も内部ハンドルを返すのは云々って言ってあげないのか
86:デフォルトの名無しさん
07/09/29 23:58:29
>>85
流れ嫁よ
87:デフォルトの名無しさん
07/09/30 08:55:39
hoge.hの中で
class hoge {
public:
virtual double CalcF1(Double_t r) const throw(std::exception);
}
hoge.cxxの中で
double hoge::CalcdF1dr(Double_t r) const throw(std::exception)
{
}
としてるんだけど、g++でcompileしようとすると
src/hoge.cxx: In member function 'virtual double hoge::CalcdF1dr(Double_t) const':
src/hoge.cxx:87: error: expected primary-expression before ';' token
と怒られます。どこが書き方間違ってるんでしょうか。
88:デフォルトの名無しさん
07/09/30 08:56:33
あ、ごめん。
class hoge {
public:
virtual double CalcdF1dr(Double_t r) const throw(std::exception);
}
でした。
89:デフォルトの名無しさん
07/09/30 08:57:57
あ、ごめん。勘違い。
スルーして下さい。
90:デフォルトの名無しさん
07/09/30 18:33:43
VC2003で作られた 静的なlibは、
VC2005でリンクすることは不可能なんですか?
91:デフォルトの名無しさん
07/09/30 20:19:13
クラスの内側で定義したクラステンプレートを特殊化する、
class X {
template<typename T> class Y {};
template<> class Y<int> {};
};
のようなコードは、VC++(2003/2005)ではコンパイルできますが、g++3/4では
error: explicit specialization in non-namespace scope ‘class X’ というエラー
になってしまいます。
Y<int>をXの中ではなく、名前空間スコープで
template<> class X::Y<int> {};
と書けばg++でもVC++でも問題なく特殊化できることは知っているのですが、
なんとかg++で、特殊化されたクラスの定義をXの中に書く方法はないでしょうか?
Y<T>とY<int>の定義が離れた場所にあると、コードが読みにくいと思うのです。
boost(特にmpl)の使用は歓迎です。
よろしくおねがいします。
92:デフォルトの名無しさん
07/09/30 20:27:59
>>89
クラス末尾にセミコロンがありませんでした。ごめんなさい。
とちゃんと書こうYO!
93:デフォルトの名無しさん
07/09/30 20:42:48
>>91
定義位置を近づけたいなら、両方クラス外に書けばいいんじゃね?
94:91
07/09/30 20:45:33
>>93
ああ、たしかにそうですね。他に案がなければそうしたいとおもいます。
ただ、Y<T>とY<int>を両方クラス内に書けると、宣言と定義の位置も離れない(定義だけになる)ので、
より読みやすいと思っています。
というわけで、引き続きお願いします。
95:デフォルトの名無しさん
07/09/30 20:54:22
>>91
規格ではネストされたクラス内での明示的特殊化は禁止されているけど
部分特殊化はOKなので、
class X {
template <typename T, class U = void> class Y {};
template <typename T>
class Y< T
, typename boost::enable_if<
typename boost::is_same< T, int>
> > {};
};
のようにenable_ifとis_sameを使って書くといいっぽい(初心者スレから一部拝借w)
VCでコンパイル可能なのはmsの独自拡張でgccの方が正しいとのこと
96:91
07/09/30 20:57:38
なお、メンバ関数テンプレートで同様のエラーをくらう件については
(下記の2行めがエラーになる)、
class X {
template<typename T> void foo(T x) {}
template<> void foo<int>(int x) {} // error
};
下記方法でごまかしています。
#include <boost/type.hpp>
class X {
void foo_(int x, boost::type<int>) { /* specialized */ }
template<typename T> void foo_(T x, ...) {}
public:
template<typename T> void foo(T x) { foo_(x, boost::type<T>()) ;}
};
97:91
07/09/30 20:59:12
>>95
部分特殊化はOKだったんですか。気づきませんでした。
早速試してみます。どうもありがとう~!!
98:デフォルトの名無しさん
07/09/30 21:00:46
>>91
私はC++初心者ですが、>>93さんと同意見です。
>>95さんの言うようにgccの方が正しい(つまり規格どおりということですよね)ならば、
なおさらそう思います。
それに、Xクラスの定義を見たいときには、むしろYは外にあった方が見やすいのではないでしょうか?
99:デフォルトの名無しさん
07/09/30 21:06:58
ちなみに関数テンプレでもこの手は使えるようだ
この手法も名前があったと思うけど思い出せない
使うなら適当にローカルなメタ関数を専用の名前空間に自作して階層を浅くする工夫が必要だね
使ってればわかるけど、凄く見にくくなるから
100:デフォルトの名無しさん
07/09/30 21:10:12
あ、::type付けわすれた…
101:デフォルトの名無しさん
07/09/30 21:43:54
読み易くするのが目的で読みにくくなる手法を選ぶか。
>>99 名前があるならソレをコメントに書いておけば良いかも。
102:デフォルトの名無しさん
07/09/30 22:00:44
>>98 >>101
読みやすいかどうかは読み手にもよるし、あまり>>91や>>94はよい聞きかたではなかったですね。
C++のコードを自動生成するツール(自作)の都合でX内に定義を書けると嬉しい、というのが実際の事情です。
103:91
07/09/30 22:32:03
102は91です。
>>99
concept-controlled polymorphism ですか?
104:デフォルトの名無しさん
07/09/30 23:06:47
>>100
> あ、::type付けわすれた…
検索エンジン経由で来るひとのために、一応訂正版貼っときますね。
#include <cstdio>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
struct X {
template<typename T, typename U = void> struct Y {
Y() { std::printf("genecic\n"); }
};
template<typename T> struct Y <T, typename boost::enable_if<boost::is_same<T, int> >::type> {
Y() { std::printf("specialized for int\n"); }
};
};
class Z {};
int main() {
X::Y<Z> a;
X::Y<int> b;
X::Y<float> c;
}
実行結果は、
genecic
specialized for int
genecic
です。
105:91=104
07/09/30 23:31:30
boostが使えない場合は、VC++2003/2005/g++対応だけ考えるならこんな感じでしょうか。
#include <cstdio>
namespace b00st {
template <bool B, class T = void>
struct enable_if_c {
typedef T type;
};
template <class T>
struct enable_if_c<false, T> { /* NO TYPEDEF! */ };
template <class Cond, class T = void>
struct enable_if : public enable_if_c<Cond::value, T> {};
template<bool b> struct bool_ {
static const bool value = b;
};
template<typename T, typename U>
struct is_same : bool_<false> {};
template<typename T>
struct is_same<T, T> : bool_<true> {};
}
using namespace b00st;
struct X {
template<typename T, typename U = void> struct Y {
Y() { std::printf("genecic\n"); }
};
template<typename T> struct Y<T, typename enable_if<is_same<T, int> >::type> {
Y() { std::printf("specialized for int\n"); }
};
};
そろそろウザいとおもうので、これで打ち止めにします。ありがとうございました。
106:デフォルトの名無しさん
07/09/30 23:40:10
このtemplate感、実に小気味良い 久しぶりにC++スレを実感した
107:デフォルトの名無しさん
07/10/01 00:01:02
キモ
108:デフォルトの名無しさん
07/10/01 00:04:13
小気味良いのは確かだけど、言葉遣いが丁寧すぎてちょっと痒い、というのが俺の感想。
うん、俺の感想なんかどーだっていいってのは承知。
109:デフォルトの名無しさん
07/10/01 02:02:08
>>99
enable_ifの関数テンプレへの適用で質問。ある条件で2つの関数を呼びわけたいときは、こんな感じにすればいいみたいだけど、
template<typename T>
static void foo(T t, typename boost::disable_if<boost::is_same<T,int> >::type* = 0) {
}
template<typename T>
static void foo(T t, typename boost::enable_if<boost::is_same<T,int> >::type* = 0) {
// intへの特殊化版
}
3つ以上を呼びわけるにはどうすれば? たとえば、
template<int V>
static void boo(typename boost::enable_if_c<V == 0>::type* = 0) { }
template<int V>
static void boo(typename boost::enable_if_c<V == 1>::type* = 0) { }
template<int V>
static void boo(typename boost::disable_if_c<V == 0 || V == 1>::type* = 0) {
// default
}
とかだと、default caseな関数の引数が大変なことになってしまうような。
boostスレのほうがいいのかな。。
110:デフォルトの名無しさん
07/10/01 02:51:44
複雑な場合はmplの出番になるんじゃないかな
mpl::if_< ...,
mpl::if_< ...,
> >::type::call();
111:109
07/10/01 03:23:49
>>110
すみません、それはどこに書くコードなんでしょうか?
call() とは一体。。
112:109
07/10/01 03:28:24
>>110が理解できず、独自に考察を進め中。
template<int V>
static void boo(typename boost::enable_if_c<V == 0>::type* = 0) {}
は、
template<int V>
static void boo(typename boost::enable_if<
boost::is_same<
boost::mpl::int_<V>,
boost::mpl::int_<0>
>
>::type* = 0) {}
であり、さらに
template<int V>
static void boo(typename boost::enable_if<
typename boost::mpl::lambda<
boost::is_same<
boost::mpl::_1,
boost::mpl::int_<0>
>
>::type::apply<boost::mpl::int_<V> >::type
>::type* = 0) {}
だから、この数値0-Nでlambdaしたのをmpl::listで抱えて、特殊化版はlistのat<i>したのでenable_ifして、default版はこれらをandでfoldしたのにdisable_ifすればいいと思うんだぜ?
・・・絶対方向が間違ってる。
113:デフォルトの名無しさん
07/10/01 03:37:53
いや、単に、mpl::if_で関数を実装したクラスを選んで呼び出す
boost/smart_cast.hppが参考になるかも
114:デフォルトの名無しさん
07/10/01 03:44:43
>>113
私は、単に boo(0); boo(1); boo(2); とだけ書くと、呼び先の関数がコンパイル時に決まるようにしたいと
思っているんですが、>>110は、このbooを *呼ぶ側* をif_で工夫しろということ?
まぁ、boo()でif_を使って、適切なboo_()を呼ぶようにしてもいいのかもしれませんが、
委譲してしまうとタグディスパッチと大差ないようにも思うし。。
なんか勘違いしてたらすんません。smart_castは早速見てみます。
115:デフォルトの名無しさん
07/10/01 04:37:09
どうしてもenable_ifを使いたいなら
複雑な条件を書かずに済ますことは不可能だと思う
116:109
07/10/01 05:41:56
>>115
enable_ifが使いたいわけでは無くて、
1.メンバ関数テンプレートの特殊化(相当のこと - オーバーロードでもいい)を行いたい
2.特殊化の定義は、クラス内に書きたい (>>91と同じく, 見た目の問題で)
3.メンバ関数を呼ぶ側はあまり難しいことを考えたくない
4.タグディスパッチのような別関数への処理の委譲は、できれば避けたい (これも見た目の問題で)
という条件で、Pという場合と!Pという場合の処理の振り分けだったら、
enable_ifを使ったオーバーロードでOKとわかった(>>109)が、P, Q, (!P && !Q)
の3関数に振り分けたい場合にこの4条件を満たすようなのないですかね?
というのが質問です。ちゃんと書かずにすみません。コンパイラはgccです。
117:デフォルトの名無しさん
07/10/01 05:47:44
>この4条件を満たすようなのないですかね
自分で書いた>>109が満たしてると思うんだが
118:デフォルトの名無しさん
07/10/01 05:58:35
>>117
おっしゃる通りなんですが、>>109は、V==0やV==1という条件が
繰り返し登場してしまい、メンテナンス性がいまいちかなと思いまして。
実際はenumとか扱いたいので。
109の繰り返しになりますけど、条件1-4をみたし、かつdefault case
template<int V>
static void boo(typename boost::disable_if_c<V == 0 || V == 1>::type* = 0) { /* default */ }
を綺麗にかけないですかね。
template<int V> static void boo(...) { /* default */ }
とかが通れば最高なのに。
119:デフォルトの名無しさん
07/10/01 06:02:23
struct a_condition : mpl::bool_<...> {};
としてenable_ifに渡すとか
120:デフォルトの名無しさん
07/10/01 09:08:09
kwsk
121:デフォルトの名無しさん
07/10/01 09:54:53
引数忘れた
こんな感じ
enable_if< my_conditionA<V> >
まあディスパッチすべきだな
enable_ifはこの場合必要ないから
122:デフォルトの名無しさん
07/10/01 11:56:27
デザパタのプロトタイプパターンを使ってみたいのですが
ばらばらに clone() 関数をとりつけるよりも
ひとつ Clonable クラスを作って、そのクラスから
継承したほうがよいでしょうか?
123:デフォルトの名無しさん
07/10/01 12:34:46
そういう継承ってどうなんだろうね。
124:デフォルトの名無しさん
07/10/01 17:41:51
noncopyableとかあるし、いいんじゃね?
125:デフォルトの名無しさん
07/10/01 18:16:10
traitsを作れば継承はいらないと思うよ
126:デフォルトの名無しさん
07/10/02 21:42:40
#include <boost/numeric/ublas/vector.hpp>
using namespace boost::numeric::ublas::inner_prod;
VC++2005EEの環境でビルドすると、
error C2867: 'boost::numeric::ublas::inner_prod' : は名前空間ではありません。
というエラーが出ます。
エラーの原因は何ですか?
127:デフォルトの名無しさん
07/10/02 22:08:58
名前空間ではないものをusing namespaceしたこと
128:126
07/10/02 23:00:22
>>127
URLリンク(sealsoft.jp) このサイトの
> usingを使って、ある識別子をグローバルな名前空間に持ち上げることができる。こうするとその後は大域解決演算子を使う必要がない。
> using namespace seal::foo;
> // 関数fooを呼び出す
> int a = foo();
ここ見てできると思ったんですけど、このサイト間違ってますか?
129:デフォルトの名無しさん
07/10/02 23:27:47
usingディレクティブ (using namespace)の対象にできるのは、名前空間だけ。
代わりといってはアレだが、その他の識別子一般には、using宣言が使える。
using boost::numeric::ublas::inner_prod;
130:126
07/10/02 23:49:25
>> 129
なるほど、そうなんですか。
URLリンク(msdn2.microsoft.com)(vs.80).aspx
ここを勘違いして見てました。(classの中のusingとは別物なんですね)
クラスの中でnamespace内の関数をusingしたい場合、
class A {
using boost::numeric::ublas::inner_prod;
};
エラーになってしまうのですが、クラス中でnamespace内の関数をusingするのは無理ということですか?
131:デフォルトの名無しさん
07/10/03 00:09:31
そういうこと。クラス定義内のusingは基底クラスの名前を指定することに特化している。
なお、型名だけはtypedefで代用できる。
132:126
07/10/03 00:14:05
ありがとうございました。
133:デフォルトの名無しさん
07/10/03 01:54:49
マクロ使って、行数と引数を連結させたいのですが、
#define macro( name )\
const char *x = "name##__LINE__";
とかやってもできません。
こんなことは可能ですか?
134:デフォルトの名無しさん
07/10/03 02:05:02
__LINE__は定数だからダブルクォーテーションで囲っちゃだめっしょ
で、定数を文字列にするのは単純なマクロじゃ厳しいと思うけど・・・
おとなしく関数にしたほうがよさそう
135:デフォルトの名無しさん
07/10/03 02:07:38
一応マクロでこんな感じでいかが?
#define macro( buf, name ) sprintf( buf, "%s%d", "name", __LINE__);
136:デフォルトの名無しさん
07/10/03 02:10:53
#define NUM2TEXT_(n) #n
#define NUM2TEXT(n) NUM2TEXT_(n)
#define macro(name) \
const char *x = name ## NUM2TEXT(__LINE__)
137:デフォルトの名無しさん
07/10/03 02:43:41
演算子オーバーロードって副作用完了点のことも考慮しないといけないんですか?
std::cout << "test" << std::endl;
で (a) "test" << std::endl; が先に評価されて、次に std::cout << (a) が評価される、という事態にはならないんですか?
138:デフォルトの名無しさん
07/10/03 03:26:56
優先順位の同じ演算子の並びは左から評価じゃなかったのか
139:デフォルトの名無しさん
07/10/03 04:07:20
左結合と右結合があってね・・・
140:133
07/10/03 05:13:05
ありがとうございます。
>>136さんのは
どういう原理なんでしょうか?
141:デフォルトの名無しさん
07/10/03 08:46:05
7**7**7 の下一桁の数字は?
142:デフォルトの名無しさん
07/10/03 09:44:47
>>137
多重定義されている場合、通常の関数と同様、
呼出の直前に副作用完了点が現れるので心配は要らない。
<<は左結合だから、まずstd::cout << "test"から取り掛かる。
これは多重定義されているので、std::cout.operator <<("test")という関数呼出に相当。
関数呼出の直前には副作用完了点が来るので、ここまでにstd::coutと"test"が評価される。
と言っても、共に副作用を持たないので何も起きないが。
仮に副作用を持つ式だった場合、通常の関数呼出同様に
<<の左側と右側のどっちのオペランドが先に評価されるかは決まっていない。
std::cout.operator <<("test")の戻り値をrとすると、
次にr << std::endlの評価に掛かる。以下同じ。
143:デフォルトの名無しさん
07/10/03 11:51:51
>>140
> 16.3.2 The # operator
> 16.3.3 The ## operator
144:デフォルトの名無しさん
07/10/03 13:50:35
>>133
#define XY(X,Y) X##Y
#define MAKENAMEXY(FX,LINE) XY(FX,LINE)
#define MAKENAME(FX) MAKENAMEXY(FX,__LINE__)
というマクロで連結させている例がある。
評価順その他の関係で、間に一段置かないとならないらしい。
145:デフォルトの名無しさん
07/10/04 00:31:45
VS2008EEで>>136が正常に動作しないんだけど・・・
コンパイラの仕様かな?
146:デフォルトの名無しさん
07/10/04 00:36:58
プリプロセッサの仕様じゃね?とかつまんない事言うね。義務として。
147:デフォルトの名無しさん
07/10/04 00:45:12
すみません。継承について質問です。
クラスBaseを基底とするクラスDerivAやクラスDerivBがあるとして、
そこからインスタンスを作成するとすると、
Base* pA = new DerivA;
Base* pB = new DerivB;
となると思います。
そこから、pAもしくはpBから新たなインスタンスpCを作りたいと思っているのですが、
どうしたらいいでしょうか?
単にpA(DerivA)だけであれば、DerivA *pC=*pAだけでいけるのですが、
pAとpB(最終的にはBaseを基底とするクラス全部)にも対応できるものを作りたいので、
どうか力をお貸しください。
148:デフォルトの名無しさん
07/10/04 00:53:05
class Base {
public: virtual Base *NewInstance() = 0;
};
class DerivA : public Base {
public: virtual Base *NewInstance(){ return new DerivA; }
};
class DerivB : public Base {
public: virtual Base *NewInstance(){ return new DerivB; }
};
Base *pA = new DerivA;
Base *pB = new DerivB;
Base *pC = pA->NewInstance();
Base *pD = pB->NewInstance();
149:デフォルトの名無しさん
07/10/04 00:53:41
Base* pA = new DerivA();
Base* pB = new DerivB();
150:147
07/10/04 01:02:02
>>148、149
目からウロコが落ちました。
インスタンスを作成する関数を別途で作ればいいわけですね。
ありがとうございます。
151:デフォルトの名無しさん
07/10/04 01:04:17
>>148
DerivA::NewInstanceはDerivA*を返し、
DerivB::NewInstanceはDerivB*を返し、
という具合に、そこは共変にしてほしいな。
152:デフォルトの名無しさん
07/10/04 01:06:08
凶変を許したことでできるようになったことってなんだっけ?
なんかの本にかいてあったが忘れた
153:デフォルトの名無しさん
07/10/04 01:15:57
>>136
boostにはなんて名前で入ってたっけ
154:デフォルトの名無しさん
07/10/04 01:18:23
>>152
pAはDerivA*と分かっているとき、
DerivA* pA2 = static_cast<DerivA*>(pA->NewInstance());
のようなキャストを型安全性を損なうことなく排除できる。
155:デフォルトの名無しさん
07/10/04 02:07:15
dynamic_castすれば共変なしでも安全じゃね?
156:デフォルトの名無しさん
07/10/04 02:08:25
URLリンク(videointroplayer.web.fc2.com)
157:デフォルトの名無しさん
07/10/04 02:29:39
>153
BOOST_PP_STRINGIZE
158:デフォルトの名無しさん
07/10/04 08:19:17
これじゃだめなん?
Base *pC = new DerivC;
159:デフォルトの名無しさん
07/10/04 08:20:10
Base *pC = new DerivC(pA);
Base *pC = new DerivC(pB);
160:デフォルトの名無しさん
07/10/04 21:28:42
>>155
それだと余計な負荷がかかる。
161:デフォルトの名無しさん
07/10/05 01:29:04
俺的c++開発環境構築メモ
目的:最終的にlinuxで動かせるようにしないといけないけどVisual Studio捨てれない
winxpにvmwareいれてゲストOSとしてubuntu7を入れる
ubuntuの/home/srcをsambaで共有できるようにしてホストOSのwinxpからみれるようにする
/home/src = \\ubuntu\src
の下にVisual Studioのプロジェクト作成
makefileはeclipse/CDTで自動生成
あとはemacsでメインのコードの編集するけど、flymakeとか使いつつ
インテリセンスも使えてeclipse/cdtのリファクタリング機能も使える環境のできあがり
162:デフォルトの名無しさん
07/10/05 04:20:16
俺がいる
163:デフォルトの名無しさん
07/10/05 08:18:16
もう遅いだろうがcoLinuxを薦めてみる
164:デフォルトの名無しさん
07/10/05 12:27:41
coMomongaを勧めてみる
165:デフォルトの名無しさん
07/10/05 12:59:49
coLinuxの方が便利なの?
速度が速い以外のメリットがないなら、もう乗り換えれない
166:デフォルトの名無しさん
07/10/05 15:23:45
coLinuxってkernelのバージョンあがるたびに中身を全消ししないといけないって聞いたのだけど
違うの?
167:デフォルトの名無しさん
07/10/05 17:36:55
ヘッダファイルなどで記述したグローバルなstatic変数は,
includeしたソースが複数ある(各ソースではincludeガードが起きずに展開される)
場合も単一の存在となるんでしょうか?
それとも別々の独立した変数となるんでしょうか?
168:デフォルトの名無しさん
07/10/05 17:41:00
それをインクルードしたソースファイルごとに別々に作られることになる
169:デフォルトの名無しさん
07/10/05 18:02:52
ありがとうございます.
あれ,でもクラス変数などは単一なんですよね?
うーむ,基本の理解が全然出来ていない.
170:デフォルトの名無しさん
07/10/05 18:26:17
クラスの static 変数はどこかで1個だけ実体を定義する必要がある。
class A{
static int x;
};
int A::x; // <-- これ
2個以上のソースファイルで定義したら、定義が重複してるってリンクエラーになる。
static でない普通のグローバル変数と同じあつかい。
171:デフォルトの名無しさん
07/10/05 20:36:51
#includeは単にファイルをくっつけてるものと考えれば理解しやすいかも