1

ポリモーフィズムを使用するために、メモリフットプリントが異なるいくつかの具象クラスによって実装された抽象クラスがあります。

#include <iostream>
using namespace std;

class abstractFoo {
public:
    virtual void method() = 0;
};

最初の具体的なクラス:

class concreteFoo1 : public abstractFoo {
private:
    int member1;
public:
    concreteFoo1() {
        cout << "Constructing Foo1" << endl;
        member1 = 1;
    }
    virtual void method() {
        cout << "Foo1 member: " << member1 << endl;
    }
};

別の具体的なクラス:

class concreteFoo2 : public abstractFoo {
private:
    int member1;
    int member2;
public:
    concreteFoo2() {
        cout << "Constructing Foo2" << endl;
        member1 = 2;
        member2 = 3;
    }
    void method() {
        cout << "Foo2 members: " << member1 << ", " << member2 << endl;
    }
};

私がやりたいのは、抽象型のオブジェクトを宣言し、それを関数のパラメーターとして渡して、具象型またはabstractFooのいずれかのオブジェクトとして作成することです。私は最初に通常の方法を使用し、パラメーターにポインターを渡します。concreteFoo1concreteFoo2

enum typeFoo {FOO1, FOO2};

void createFoo(typeFoo type, abstractFoo *foo) {
    switch (type) {
    case FOO1:
        foo = &concreteFoo1();
        break;
    case FOO2:
        foo = &concreteFoo2();
        break;
    }
}

int main() {
    abstractFoo *foo = new concreteFoo1();
    createFoo(FOO2, foo);
    foo->method();        //Not expected result!
    return 0;
}

出力は次のとおりです。

Constructing Foo1
Constructing Foo2
Foo1 member: 1

問題はfoo、抽象型のオブジェクトとして初期化できないことconcreteFoo1です。この例のように、として初期化すると、メソッドfooを呼び出した後でも、ポインターはそれを指しますcreateFoo

それを機能させるために、私はパラメータのポインタにポインタを渡すように言われました:

enum typeFoo {FOO1, FOO2};

void createFoo(typeFoo type, abstractFoo **foo) {
    switch (type) {
    case FOO1:
        *foo = new concreteFoo1();
        break;
    case FOO2:
        *foo = new concreteFoo2();
        break;
    }
}
int main() {
    abstractFoo *foo = new concreteFoo1();
    createFoo(FOO2, & foo);
    foo->method();        //Expected result
    return 0;
}

出力:

Constructing Foo1
Constructing Foo2
Foo2 members: 2, 3

このソリューションは機能しますが、あまり満足していません。抽象型へのポインタを作成できないため、使用しないオブジェクトを作成する必要があり、astractFoo* foo = new concreteFoo1()それに割り当てられたメモリが解放されることはありません。 、だから私はメモリリークで終わると思います。

AbstractFoo**オブジェクトを作成せずに、抽象型へのポインターへのポインターを作成する方法はありますか?

それで、ダブルポインターが私の問題の厳密な解決策であることを確認できますか?もしそうなら、私の2つの問題に答えることができますか?そうでない場合は、どうすればよいですか?

4

2 に答える 2

1

を戻り型として使用しstd::unique_ptr<abstractFoo>、それをファクトリパターンと組み合わせると、メモリ割り当ての問題と作成の問題の両方を解決できます。

virtualにデストラクタが必要であることに注意してくださいabstractFoo

ダブルポインタはC++で行うことではありません。これはCの余りです。参照によってポインターを渡すと、C++っぽくなります。ポインターを使用しませんが、C++っぽい場合は代わりにスマートポインターを使用します。

于 2012-12-09T16:12:53.250 に答える
0

さて、演算子を使用してポインタを作成できることがわかったnewので、私自身の質問に答えます。

enum typeFoo {FOO1, FOO2};
void createFoo(typeFoo type, abstractFoo **foo) {
    switch (type) {
    case FOO1:
        *foo = new concreteFoo1();
        break;
    case FOO2:
        *foo = new concreteFoo2();
        break;
    }
}
int main() {
    abstractFoo **foo = new abstractFoo*;
    createFoo(FOO2, foo);
    abstractFoo *foo2Ptr = *foo;
    foo2Ptr->method();        //Expected result
    delete foo2Ptr;
    createFoo(FOO1, foo);
    abstractFoo *foo1Ptr = *foo;
    foo1Ptr->method();        //Expected result
    delete foo1Ptr;

    return 0;
}

出力:

Constructing Foo2
Foo2 members: 2, 3
Constructing Foo1
Foo1 member: 1

特に参照またはスマートポインタを使用する必要がある場合は、コメントはありますか?

于 2012-12-10T09:50:22.800 に答える