2011-08-17 10 views
0
class A 
{ 
public: 
    A(int i):pi(&i){} 
    int* func() 
    { 
    //dosomething 
    return pi; 
    } 
private: 
    int*pi; 
}; 

class B:public A 
{ 
    A*pa; 
public: 
    int* bar() 
    { 
     //dosomething 
     return pa->func(); 
    } 
}; 

int main() 
{ 
    A*pa=new B(); 
    int*pi=pa->bar(); 
    delete pa; 
    return 0; 
} 

は、誰かが任意のヒントを提供していただけますか?私は間違った選択をすることをちょっと心配しています。継承とポインタが使用しています - 私の上記のクラスは、(私はより良いビューのために、それは小さな狭く)を入力してもいいです場合は、正しい使用のためのアドバイス

+0

「クラスA」仮想デストラクタはどこですか? – sharptooth

+0

答えることは不可能です。あなたは何をしようとしているのですか? –

+1

私は良いC + +の本を取得し、そこから開始することをお勧めします。あなたは明らかに*継承*の概念を理解していません! – Nim

答えて

-2

投稿したコードが間違っていて、混乱しています。

A*pa=new B(); 
    int*pi=pa->bar(); 

それはできません! Bにはbar()関数はありませんが、Bオブジェクトを作成するとAにキャストします(実際には欠けています)。

あなたは正確にやりたいことはわかりませんが、私はそれがインターフェイスに似たものになると思います。 あなたは(純粋な)仮想関数のセットを定義する抽象基本クラスを持ち、 "loadData、saveData"などの固定機能セットを記述しますが、この機能の実装方法は記述しません。 NOTE

class YourInterface { 
public: 
    YourInterface(){ 
    } 

    virtual ~YourInterface(){ 
    } 

    virtual void saveData(Data data) = 0; //Pure virtual = Childs are forced to implement those functions to become non abstract 
    virtual Data loadData() = 0; 
}; 

//One implementation to load and save data to/from a xml file 
class XmlImplementation : public YourInterface { 
public: 
    XmlImplementation(){ 
    } 

    virtual ~XmlImplementation(){ 
    } 

    //Overriding functions: 
    void saveData(Data data){ 
     //Save data to a xml file here 
    } 

    Data loadData(){ 
     //Load data from a xml file here 
    } 
}; 

void main(){ 
    YourInterface* p; 
    p = (YourInterface*) new XmlImplementation(); 

    p->loadData(); //We just want to get our Data here, we dont care whether its from a xml or binary file etc. 
} 

:用 申し訳ありません:あなたは(一つは、そのためのストリームを使用しますが、私の場合を例としてこれを使用しますのでご注意ください)など、実際にXMLファイルにデータを保存するか、単にプレーンバイナリとしてすることができます未完成の投稿私は誤ってボタンを押す

+0

ベースクラスへのキャストポインタは暗黙的なので、キャストが欠落していません。一方、あなたはCスタイルのキャストを使用します。これは、特にC++について誰かに教えるときには、C++ **で行うべきではありません。問題は、 'p =(YourInterface *)new int(42)'が黙ってコンパイルされますが、それは間違っています。ベースにキャストする場合は、サブクラスにキャストする場合は常に 'static_cast'または' dynamic_cast'を念頭に置いてください。 –

+0

それについて申し訳ありません、ちょうど私がキャストされたhavent最後に時間が問題を抱えていたことを思い出しました。 – Paranaix

+0

問題があった場合は、別の問題があったためです。うまく設計されたC++コードは、 "関数型"の "キャスト"(実際には一時インスタンスを作成する要求)以外のキャストは必要ありません。 –

0

あなたのコードにはいくつかの問題があります。ここにいくつかあります:

A(int i):pi(&i){} 

値によって渡される引数のアドレスを取得しています。 iは、Aのコンストラクタが復帰したときにはもう存在しません。

A*pa; 

B::paは決して初期化されません。

delete pa; 

正しく動作させるには、Aに仮想デストラクタを追加する必要があります。

+0

'delete'は問題です。あなたはBのクラスAの開始前にオフセットがないという保証はありません。 –

+0

@Let_Me_Be:Aは仮想デストラクタを持っていないので、それは単なる問題です。これは、AがBのオフセットで開始するのに対し、コンパイラは、ポインタがA型の場合、実際のAの実際の開始点を指し、仮想デストラクタはBの開始点を正しく見つけることを保証するからです。 –

+0

@ Janは、クラスが多相である場合、deleteは適切なポインタを正しく解放します。仮想デストラクタは必ずしも必要ではありませんが、この問題を防ぐために非仮想デストラクタを使用することもできます。 –

1

コードにはいくつか問題があります。一つ目は、このパラメータiを指すようにメンバーpi設定ここ

A(int i):pi(&i){} 

です。ただし、コンストラクタが完了するとすぐにiが消えます。今どこにも指し示していないポインタがあります!

クラスBは全く任意のユーザ定義のコンストラクタを持っていないここに

class B:public A 
{ 
    A*pa; 

同様の問題。つまり、paは決してどこにでも向けることができません。基本クラスへのポインタを介してオブジェクトを削除する場合

第三の問題は、基本クラスが仮想デストラクタがある場合のみ動作

A*pa=new B(); 
// ... 
delete pa; 

主です。

コードをコンパイルしようとすると、コンストラクタに関するいくつかの追加の問題が見つかります。

関連する問題

 関連する問題