859 :
デフォルトの名無しさん:04/10/20 17:57:11
すいません、質問です。下のプログラムを g++ -Wall でコンパイルすると
T.cc:9: warning: `struct NonVirtualClass' has virtual functions but non-virtual destructor
って怒られるんですが、原因が理解できません。
~X(){} がなければ怒られないのですが・・・
ちなみに g++ のバージョンは 3.3 です。
struct X {
~X() {}
};
struct VirtualClass {
virtual void Method() = 0;
};
struct NonVirtualClass : VirtualClass {
X m;
void Method() {}
};
>>859 g++は警告出してくれるんだ・・・やさしいなぁ・・・。
struct X {
virtual ~X() {}
};
>>864 struct VirtualClass {
virtual ~VirtualClass() {}
virtual void Method() = 0;
};
仮想デストラクタが必要なのはこっちだろ。
866 :
859:04/10/20 18:14:46
おい、ちょっとまて。
>~X(){} がなければ怒られないのですが・・・
これどーゆーいみよ。
>>869 ~X() があればクラスだっていうのか?
871 :
デフォルトの名無しさん:04/10/20 21:40:55
うまくつながってないんじゃ?
>>868 ~X() があると NonVirtualClass にもコンパイラによって自動的にデストラクタが作成される。
おそらくg++はこの暗黙のデストラクタをvirtual指定無しとして扱って件の警告が出るのではないかと。
>>872 デストラクタのあるメンバを置いただけでも警告が出るようになるな。
12.4 Destructors の -3- -4- に従って
non-trivial なデストラクタを持つかどうかが警告の出る条件になるんだろう。
874 :
デフォルトの名無しさん:04/10/21 00:10:31
これってどうよ?
#include <iostream>
using namespace std;
class CBase
{
int m_id1;
public:
CBase(int id1 = 1):m_id1(id1){}
int GetID1() const { return m_id1; }
};
class CDerived : public CBase
{
int m_id2;
public:
CDerived(int id2 = 1):m_id2(id2),CBase(id2*10){}
int GetID2() const { return m_id2; }
};
class CFactory
{
protected:
CFactory(){}
public:
static CBase* GetInstance(){ return new CBase(111); }
};
int main()
{
CBase* p = CFactory::GetInstance();
cout << ((CDerived*)p)->GetID2() << endl;
}
876 :
デフォルトの名無しさん:04/10/21 00:17:59
>>876 エスパー以外は初心者か。おめでてーな。
「どうよ」っていう言葉ってどうよ?
ただのダウンキャストがどうかしたのか
どうよもくそもねぇじゃん。
まじめに読んで損した。
882 :
デフォルトの名無しさん:04/10/21 00:49:06
QueryInterface がどうだかって言いたいのか?
ファクトリを持ち出したところに何か隠された意味があるのではなかろうか
だめ!!もう限界。
>>874、答えを教えてください。
template<class T> T* Allocate( ptrdiff_t n, T* ) {
return (T*)operator new((size_t)n * sizeof (T));
}
こんなnewの使われ方をはじめて見たのですが、なにを表しているのですか?
動作させてみたところ、指定したサイズを確保し、コンストラクタは呼ばれないようですが。
「プログラミング言語C++第3版 」を買えばこういったことがすべて書いてありますでしょうか?
>>886 通常のnew演算子で呼び出されるメモリ確保の直接呼出しです。
その本には確かに書いてあります。
通常の方法ですか。どうもです
STLの中身を見ていたら上記のような疑問が山ほど出てきて一人で1000レス行きそうな勢いなので
素直に「プログラミング言語C++第3版 」で勉強してきます
class Widget{ ... };
bool f( const Widget& w ){ ... }
int main(){
std::vector<Widget> v;
std::find_if( v1.begin(), v1.end(), std::not1( std::ptr_fun( &f ) ) ); //1
return 0;
}
1で、
error C2529: '_Left' : 参照への参照は無効です。
warning C4181: 参照型に適用された修飾子は無視されました。
とエラーが出てしまいます。どうすればうまくいきますでしょうか…?
コンテナを vector<Widget*> にして bool f( const Widget* w ) にすれば
ちゃんと動いたのですが、こうするしか解決方法はありませんでしょうか?
そこでboostですよ
891 :
デフォルトの名無しさん:04/10/21 23:06:15
そこでるbyですよ。
>>889 fを関数オブジェクトに変えてmem_fun_refでいいんじゃいないの?
>889
> std::find_if( v1.begin(), v1.end(), std::not1( std::ptr_fun( &f ) ) ); //1
std::find_if( v1.begin(), v1.end(), std::not1( std::ptr_fun<Widget>( &f ) ) );
これで通りませんか?試してないのでもし通らなかったらごめんなさい.
#reference to reference問題は良いい加減修正して( ゚д゚)ホスィ…
std::find_if( v1.begin(), v1.end(), std::not1( std::ptr_fun<const Widget>( &f ) ) );
の方が適切です.すいません.
>>894 レスありがとうございます
しかし
error C2784: 'std::pointer_to_binary_function<_Arg1,_Arg2,_Result> std::ptr_fun(_Result (__cdecl *)(_Arg1,_Arg2))' : 'T3 (__cdecl *)(const Widget,T2) 用のテンプレート引数を 'bool (__cdecl *)(Widget &)' から減少できませんでした。
error C2784: 'std::pointer_to_unary_function<_Arg,_Result> std::ptr_fun(_Result (__cdecl *)(_Arg))' : 'T2 (__cdecl *)(const Widget) 用のテンプレート引数を 'bool (__cdecl *)(Widget &)' から減少できませんでした。
となってしまいます…
すいません.893, 894は誤りです.無視してください.
892さんが書いているようにfをファンクタにするのが良いと思います.
(mem_fun_refはいらないような?)
つまり
struct Hoge : std::unary_function<Widget, bool>
{ bool operator ()( const Widget& w ) const{ return false; } };
std::find_if( v1.begin(), v1.end(), Hoge() );
ということでしょうか…?
関数ではダメですか…
899 :
デフォルトの名無しさん:04/10/22 00:38:37
boostってソースしか参考にしていない…
実際に使うには標準じゃないし。。。
>>900 ばっかでーーー。
自分で使う範囲では標準など気にする必要などない。
第一、会社によってSTLすら使わせてくれない
ところがあるそうじゃないですか?俺はプログラマーじゃないから詳しくはないけど。
902 :
デフォルトの名無しさん:04/10/22 01:03:55
try〜catchの形式で一般的なものは、次のうちどちらですか?
理由も合わせて述べて下さい。
■パターンA
int hoge() {
try {
int a = 0;
a = 1;
return a;
} catch(...) {
throw;
}
}
■パターンB
int hoge() {
int a = 0;
try {
a = 1;
} catch(...) {
throw;
}
return a;
}
どうしてもエラーがでるので教えてください
class Concept{
public:
vector<int> number;
double* ave_signal;
}
class GSG{
public:
vector<Concept> m_VecConcept;
int m_length;
};
void Concept::Concept(int length){
ave_signal = new double[length * sizeof(double)];
memset(ave_signal, 0x00, length * sizeof(double));
}
のようにクラスを作っておいて、
void GSG::func(){
if (flag){
Concept *pCon = new Concept(m_length);
m_VecConcept.push_back(*pCon);
delete pCon;
}
}
ってやると、コンパイラは通るのですが実行時に
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
ってエラーが出てプログラムが強制終了してしまいます。
それもm_lengthが3の時は普通に動いて8のときは死にます。
VC6.0のMFC使ってやっているのですがここで詰まってしまいました。
分かる方教えてくださいまし。
>902
例外を投げる場所と、catch節の処理内容によるのでは。
この例ではどちらもないので、AもBも変わらないと思います。
>>904 取り敢えず、Concept::ave_signalのdeleteをしていないことと
要素数がlength * sizeof(double)なのは変だろうってことと
なんでmemset()するんだかってことが気になった。
>>904 Conceptにコピーコンストラクタ書いてないとか?