我有一个抽象类,由几个具有不同内存占用的具体类实现,以便使用多态。
#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
的对象,并将其作为参数传递给函数,该函数将其创建为具体类型concreteFoo1
或{{1的对象}}。我首先使用通常的方式,在参数:
concreteFoo2
输出是:
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()
,指向抽象类型的指针,而不构造对象?
那么,你能否确认双指针是我问题的最佳解决方案,如果是,你能否回答我的两个问题?如果没有,我该怎么办?
答案 0 :(得分:1)
如果您使用std::unique_ptr<abstractFoo>
作为返回类型并将其与工厂模式结合使用,则可以解决内存分配问题和创建问题。
请注意,您需要virtual
中的abstractFoo
析构函数。
双指针不是C ++的事情。它是来自C的余数。通过引用传递指针将更多C ++ - ish。不使用指针,而是使用智能指针,如果更多C ++ - ish。
答案 1 :(得分: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
任何评论,特别是如果我应该使用引用或智能指针?