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

好吧,这个解决方案有效,但我对此不太满意:我仍然无法创建指向抽象类型的指针,所以我必须构造一个我不会使用 in 的对象astractFoo* foo = new concreteFoo1(),并且分配给它的内存永远不会释放,所以我想我会以内存泄漏结束。

有没有办法在AbstractFoo**不构造对象的情况下创建一个指向抽象类型指针的指针?

那么,你能确认双指针是我问题的正确解决方案吗?如果是,你能回答我的两个问题吗?如果没有,我该怎么办?

4

2 回答 2

1

If you use a std::unique_ptr<abstractFoo>, as a return type and combine it with the factory pattern, you solve both the memory allocation issues and the creation issue.

Note that you'll need a virtual destructor in abstractFoo.

A double pointer is not the C++ thing to do. It's a remainder from C. Passing a pointer by reference would be more C++-ish. Not using pointers, but smart pointers instead if even more C++-ish.

于 2012-12-09T16:12:53.250 回答
0

好吧,我刚刚发现您可以使用 operator 创建指针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 回答