C++相談室 part36

このエントリーをはてなブックマークに追加
858デフォルトの名無しさん:04/10/20 17:42:11
>>857
C++はプログラミング言語だが何か。
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() {}
};

860デフォルトの名無しさん:04/10/20 17:59:07
>>859
つEffective C++
861デフォルトの名無しさん:04/10/20 18:00:27
>>859
g++は警告出してくれるんだ・・・やさしいなぁ・・・。
862デフォルトの名無しさん:04/10/20 18:06:45
>>859
つ[英和辞典]
863デフォルトの名無しさん:04/10/20 18:07:55
>>859
つI
864デフォルトの名無しさん:04/10/20 18:08:41
struct X {
virtual ~X() {}
};
865デフォルトの名無しさん:04/10/20 18:11:57
>>864
struct VirtualClass {
virtual ~VirtualClass() {}
virtual void Method() = 0;
};
仮想デストラクタが必要なのはこっちだろ。
866859:04/10/20 18:14:46
>>865
ありがとうございました!
867デフォルトの名無しさん:04/10/20 18:56:00
>>864
アホだ
868デフォルトの名無しさん:04/10/20 19:06:11
おい、ちょっとまて。
>~X(){} がなければ怒られないのですが・・・
これどーゆーいみよ。
869デフォルトの名無しさん:04/10/20 19:37:42
>>868
 クラスじゃないからだろ。
870デフォルトの名無しさん:04/10/20 21:27:10
>>869
~X() があればクラスだっていうのか?
871デフォルトの名無しさん:04/10/20 21:40:55
うまくつながってないんじゃ?
872デフォルトの名無しさん:04/10/20 22:28:54
>>868
~X() があると NonVirtualClass にもコンパイラによって自動的にデストラクタが作成される。
おそらくg++はこの暗黙のデストラクタをvirtual指定無しとして扱って件の警告が出るのではないかと。
873デフォルトの名無しさん:04/10/20 22:56:24
>>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;
}
875デフォルトの名無しさん:04/10/21 00:15:30
>>874 意味不明
876デフォルトの名無しさん:04/10/21 00:17:59
>>875
初心者は口出すなよ
877デフォルトの名無しさん:04/10/21 00:19:21
>>876
エスパー以外は初心者か。おめでてーな。
878デフォルトの名無しさん:04/10/21 00:21:07
「どうよ」っていう言葉ってどうよ?
879デフォルトの名無しさん:04/10/21 00:23:35
>>874
「結果は未定義」が正解。
880デフォルトの名無しさん:04/10/21 00:24:42
ただのダウンキャストがどうかしたのか
881デフォルトの名無しさん:04/10/21 00:27:00
どうよもくそもねぇじゃん。
まじめに読んで損した。
882デフォルトの名無しさん:04/10/21 00:49:06
QueryInterface がどうだかって言いたいのか?
883デフォルトの名無しさん:04/10/21 01:26:07
>>874
 SEGV
884デフォルトの名無しさん:04/10/21 06:56:31
ファクトリを持ち出したところに何か隠された意味があるのではなかろうか
885デフォルトの名無しさん:04/10/21 07:05:08
だめ!!もう限界。
>>874、答えを教えてください。
886デフォルトの名無しさん:04/10/21 08:18:58
template<class T> T* Allocate( ptrdiff_t n, T* ) {
  return (T*)operator new((size_t)n * sizeof (T));
}
こんなnewの使われ方をはじめて見たのですが、なにを表しているのですか?
動作させてみたところ、指定したサイズを確保し、コンストラクタは呼ばれないようですが。
「プログラミング言語C++第3版 」を買えばこういったことがすべて書いてありますでしょうか?
887デフォルトの名無しさん:04/10/21 08:32:26
>>886
通常のnew演算子で呼び出されるメモリ確保の直接呼出しです。
その本には確かに書いてあります。
888デフォルトの名無しさん:04/10/21 08:38:36
通常の方法ですか。どうもです
STLの中身を見ていたら上記のような疑問が山ほど出てきて一人で1000レス行きそうな勢いなので
素直に「プログラミング言語C++第3版 」で勉強してきます
889デフォルトの名無しさん:04/10/21 22:57:35
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 ) にすれば
ちゃんと動いたのですが、こうするしか解決方法はありませんでしょうか?
890デフォルトの名無しさん:04/10/21 23:05:12
そこでboostですよ
891デフォルトの名無しさん:04/10/21 23:06:15
そこでるbyですよ。
892デフォルトの名無しさん:04/10/21 23:08:04
>>889
fを関数オブジェクトに変えてmem_fun_refでいいんじゃいないの?
893デフォルトの名無しさん:04/10/21 23:11:12
>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問題は良いい加減修正して( ゚д゚)ホスィ…
894893:04/10/21 23:13:46
std::find_if( v1.begin(), v1.end(), std::not1( std::ptr_fun<const Widget>( &f ) ) );

の方が適切です.すいません.
895デフォルトの名無しさん:04/10/21 23:20:41
>>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 &)' から減少できませんでした。
となってしまいます…
896デフォルトの名無しさん:04/10/21 23:22:17
すいません.893, 894は誤りです.無視してください.
892さんが書いているようにfをファンクタにするのが良いと思います.
(mem_fun_refはいらないような?)
897デフォルトの名無しさん:04/10/21 23:29:38
つまり
struct Hoge : std::unary_function<Widget, bool>
{ bool operator ()( const Widget& w ) const{ return false; } };
std::find_if( v1.begin(), v1.end(), Hoge() );
ということでしょうか…?

関数ではダメですか…
898デフォルトの名無しさん:04/10/21 23:55:44
>>897
もし失望されているようならboostというライブラリを一度見てみることをお勧めします.
functionalというライブラリに改善されたファンクタアダプタがあります.
http://boost.cppll.jp/HEAD/libs/functional/negators.html
899デフォルトの名無しさん:04/10/22 00:38:37
>>874 実行したら3行目エラーでたよ
900デフォルトの名無しさん:04/10/22 00:41:25
boostってソースしか参考にしていない…
実際に使うには標準じゃないし。。。
901デフォルトの名無しさん:04/10/22 00:50:09
>>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;
}

903大学生:04/10/22 01:20:37
どうしてもエラーがでるので教えてください

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));
}
904大学生:04/10/22 01:21:20
のようにクラスを作っておいて、

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使ってやっているのですがここで詰まってしまいました。
分かる方教えてくださいまし。
905デフォルトの名無しさん:04/10/22 01:27:41
>902
例外を投げる場所と、catch節の処理内容によるのでは。
この例ではどちらもないので、AもBも変わらないと思います。
906デフォルトの名無しさん:04/10/22 01:28:05
>>904
取り敢えず、Concept::ave_signalのdeleteをしていないことと
要素数がlength * sizeof(double)なのは変だろうってことと
なんでmemset()するんだかってことが気になった。
907デフォルトの名無しさん
>>904
Conceptにコピーコンストラクタ書いてないとか?