【问题标题】:Creating an object passed as an abstract type object创建作为抽象类型对象传递的对象
【发布时间】:2012-11-27 04:01:19
【问题描述】:

为了使用多态性,我有一个由几个具有不同内存占用的具体类实现的抽象类。

#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** ,一个指向抽象类型指针的指针?

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

【问题讨论】:

    标签: c++ pointers polymorphism side-effects


    【解决方案1】:

    如果您使用std::unique_ptr&lt;abstractFoo&gt; 作为返回类型并将其与工厂模式相结合,您可以解决内存分配问题和创建问题。

    请注意,abstractFoo 中需要一个 virtual 析构函数。

    双指针不是 C++ 要做的事情。它是 C 的剩余部分。通过引用传递指针将更像 C++。不使用指针,而是使用智能指针,甚至更多 C++ 风格。

    【讨论】:

    • 感谢您的回答,但我不能将 foo 作为返回类型传递,因为在我的真实示例中,我必须传递(并创建)几个对象。我尝试将 unique_ptr 作为参数传递,但出现以下错误:error: conversion from ‘std::unique_ptr&lt;abstractFoo, std::default_delete&lt;abstractFoo&gt; &gt; (*)()’ to non-scalar type ‘std::unique_ptr&lt;abstractFoo, std::default_delete&lt;abstractFoo&gt; &gt;’ requested
    【解决方案2】:

    好吧,我刚刚发现你可以用运算符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
    

    有什么意见,特别是如果我应该使用引用或智能指针?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多