使用指针基类的=运算符的多态性

时间:2011-07-22 03:53:24

标签: c++ polymorphism clone copy-constructor assignment-operator

所以这是交易,我想我需要针对我使用的模式走另一条路线,但我想我会先得到一些专家意见。

我有一个类(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 
};

3 个答案:

答案 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()方法。