【问题标题】:polymorphism with =operator using pointer base class使用指针基类的 = 运算符的多态性
【发布时间】:2011-10-10 18:11:55
【问题描述】:

所以这就是交易,我想我需要就我正在使用的模式采取另一条路线,但我想我会先获得一些专家意见。

我有一个类 (UsingClass),它维护一个基类指针的动态列表。当向列表中添加一个新对象时,我必须弄清楚它是什么类型的对象,因为我不能真正让它以多态方式工作。下面的行标记为“这不会像我想要的那样工作!!”理想情况下,将多态地使用感兴趣的派生类中的 = 运算符,但不幸的是,它只使用 Base 类的默认 = 运算符......如果我将 Base 设为纯虚拟(基本上将其用于没有它自己的数据成员),但我真的不想让派生类拥有两者之间共有的成员(也许我只需要减少诱饵并这样做)。

我想我可能只是完全使用了错误的模式,但我不知道应该考虑哪些替代方案。

我知道代码不一定能编译,但请与我合作。提前致谢!

    //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 
};

【问题讨论】:

  • 您的问题不清楚。也许您应该首先告诉我们您真正想要实现的目标,而不是尝试修复您的解决方案......
  • 在我看来你想要一个 clone() 方法...谷歌克隆,你应该找到很多例子。
  • icu-project.org/docs/papers/cpp_report/… 这可以解决很多问题。

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


【解决方案1】:

我有一个类 (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() 方法。

【讨论】:

    【解决方案2】:

    我看到的一个问题是您正在使用 C 样式的数组来包含“基础”对象的列表。请注意,在这种情况下,数组中元素的大小将是 sizeof(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 函数。

    【讨论】:

      【解决方案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); }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多