所以这是交易,我想我需要针对我使用的模式走另一条路线,但我想我会先得到一些专家意见。
我有一个类(UsingClass),它维护一个基类指针的动态列表。在向列表添加新对象时,我必须弄清楚它是什么类型的对象,因为我无法以多态方式使其工作。下面的行标记为“这不会像我想的那样......”理想情况下,多态地使用感兴趣的Derived类中的=运算符,但遗憾的是它只对Base类使用default =运算符....如果我使Base纯虚拟可能会工作(基本上限制它使用到没有的接口)它自己的数据成员),但我真的不想让Derived类保存两者之间共有的成员(也许我只需要剪切诱饵并执行它)。
我想我可能只是完全使用了错误的模式,但我不知道应该考虑哪些替代方案。
我知道代码不一定编译但请与我合作。提前谢谢!
//code block
class Base {
protected:
int x;
float y;
string type; // default to Derived1 or Dervied2 depending on the object inst
public:
virtual int functionM(int l) = 0;
int functionN(int P);
};
class Derived1 : public Base {
protected:
int a;
public:
int functionM(int l);
float functionR(int h);
};
class Derived2 : public Base {
protected:
int b;
float r;
public:
int functionM(int l);
float functionR(int h);
};
#define MAX_ARRAYSIZE 10
class UsingClass {
private:
Base* myDerived1And2DynamicList[MAX_ARRAYSIZE];
int indexForDynamicList;
public:
void functionAddDerivedToList(*Base myInputPtr) {
if((indexForDyanmicList + 1) < MAX_ARRAYSIZE) {
if(myInputPtr->type == "Derived1") {
myDerived1And2DynamicList[indexForDyanmicList+1] = new Derived1;
*myDerived1And2DynamicList[indexForDyanmicList+1] = *myInputPtr; // THIS WILL NOT WORK LIKE I WANT IT TO!!
} else if (myInputPtr->type == "Derived2") {
myDerived1And2DynamicList[indexForDyanmicList+1] = new Derived2;
*myDerived1And2DynamicList[indexForDyanmicList+1] = *myInputPtr; // THIS WILL NOT WORK LIKE I WANT IT TO!!
}
}
} // end of void function
};
答案 0 :(得分:3)
不是检查类型,而是简单地将一个虚函数添加到类'Base'并调用它。这会将void functionAddDerivedToList(* Base myInputPtr)简化为以下内容:
void functionAddDerivedToList(*Base myInputPtr)
{
if((indexForDyanmicList + 1) < MAX_ARRAYSIZE) {
myDerived1And2DynamicList[indexForDyanmicList+1] = myInputPtr->clone();
}
}
克隆总是被实现来调用类的复制构造函数。所以在Base中,添加以下内容:
virtual Base* clone() = 0;
实现总是采用这种形式(例子是Derived1,在你的例子中是Base的子类):
virtual Base* clone() { return new Derived1(*this); }
答案 1 :(得分:0)
我看到的一个问题是你唱的C风格数组包含一个&#34; Base&#34;对象。请注意,在这种情况下,数组中元素的大小将是sizof(Base),它与sizeof(Derived1)和sizeof(Derived2)不同。两种派生也可能不同。在这种情况下,您可以做的是让数组包含Base对象的指针而不是实际对象。这将使大小统一为4个字节,您可以作为指针访问数组中的对象。因为数组现在包含指针,所以如果您只想将它们插入数组中,则不必确定类型。
void functionAddDerivedToList(Base* myInputPtr)
{
if((indexForDyanmicList + 1) < MAX_ARRAYSIZE)
myDerived1And2DynamicList[indexForDyanmicList+1] = myInputPtr;
}
如果要从阵列中访问对象,可以执行以下操作。
Base* p = myDerived1And2DynamicList[index];
p->MyMethod();
您可以相信,在这种情况下,将根据p的实际类型调用正确的MyMethod函数。
答案 2 :(得分:0)
我有一个类(UsingClass),它维护一个基类指针的动态列表。
抱歉,但你没有(语法错误)。但不要这样做。
首先,给你的Base
类一个虚拟析构函数。否则您将遇到内存泄漏。
然后,重新设计您的UsingClass
容器。给它一个给Base成员的shared_pointer向量来保存动态分配的多态对象。 (如果使用非C ++ 0x编译器,则可以使用std::tr1::shared_ptr
。)
class UsingClass {
private:
std::vector<std::shared_ptr<Base> myList;
// int indexForDynamicList; is now myList.size()
public:
void Add(Base* myInputPtr) {
myList.push_back(myInputptr);
}
// ...
};
要添加多态对象,请使用
UsingClass container;
container.add(new Base);
container.add(new Derived1);
container.add(new Derived2);
您可以通过迭代调用所有多态方法
for (size_t i = 0; i < myList.size(); ++i)
{
myList->functionM(); // give the function a more "speaking" name
}
通过使用shared_ptr
,你可以拥有许多指向一个对象的指针,而不必关心释放内存。复制指针不会复制对象(所谓的浅拷贝)。如果您确实还需要复制对象(所谓的深层复制),则您的Base
和派生类必须实现虚拟clone()
方法。