【问题标题】:linking vector of derived class type to vector of parent class type in C++在 C++ 中将派生类类型的向量链接到父类类型的向量
【发布时间】:2013-11-14 18:09:00
【问题描述】:

我处于 C++ 的初学者阶段。假设我有一个基类和一个派生类:

class Base{
 ....

}

class Derived:public Base{

 ....
}

现在我有如下两个向量,我将对一些创建基对象和派生对象执行一些操作,并将这些对象分别推回它们对应的向量:

std::vector<Base*> baseVector
std::vector<Derived*> derivedVector

我想将derivedVector 的每个元素(对象)指向baseVector 的每个元素(对象)。假设 derivedVector[2] 将有一个指向 baseVector[2] 的指针,这样我就可以随时从派生对象访问基础对象。我该怎么做?

【问题讨论】:

  • “我想将 derivedVector 的每个元素(对象)指向 baseVector 的每个元素(对象)。”什么意思,能多解释一下吗?
  • 所以您想将对象存储在 baseVector 中,并将指针存储在 derivedVector 中?
  • @FredrickGauss:我基本上想在派生对象中保留一些指针,以便它们可以指向基础对象。
  • 您关于对象、指针和向量(基数、派生数)的话很复杂。

标签: c++ inheritance vector


【解决方案1】:

您的意思不是很清楚,但如果我理解正确,您想将指向您的 Derived 对象的指针放在两个向量中。您可以通过以下方式实现:

baseVector[2] = derivedVector[2] = new Derived();

【讨论】:

    【解决方案2】:

    我认为这是您问题的重要部分:

    ... 这样我就可以随时从派生对象访问基础对象。

    答案很简单。通过继承,派生对象已经可以访问其基础对象。 这就是继承的全部意义。

    你可以保持简单:

    class Base{
        SomeBaseFunction();
    }
    
    class Derived : public Base{
        // Do not add a Base* here.
    }
    
    int main() {
        Derived *derived_object = new Derived();
        derived_object->SomeFunction();  // this works.
    }
    

    您应该在这里更清楚地考虑您的vectors。您可能只需要一个向量,而不是两个。此外,您可能应该处理vector&lt;Derived&gt;,而不是vector&lt;Derived*&gt;

    int main () {
        Derived derived_object;   // don't use `new` here, it's just awkward
    
        vector<Derived>  vector_of_objects;
        vector_of_objects.push_back(derived_object);
    }
    

    在现代 C++ 中,无论您是初学者还是专家,都不应经常使用 *new

    【讨论】:

      【解决方案3】:

      看看你是否想使用基列表来包含派生对象指针然后就可以了。但是你不能使用派生列表来保存基指针。

      也许你想要类似的东西。

      Base * pBase = new Base();
      Derived *pDerived_1 = new Derived();
      // or
      Base *pDerived_2 = (Base *)new Derived();
      // this can be anytime casted back
      Derived *pDerived_3 = (Derived*)pDerived_2;
      
      // you can also push them into base vector
      lstBasePtr.push_back(pBase);
      lstBasePtr.push_back(pDerived_1);
      lstBasePtr.push_back(pDerived_2);
      lstBasePtr.push_back(pDerived_3);
      

      【讨论】:

        【解决方案4】:

        您好,感谢您的回复。我已经弄清楚我需要做什么。不确定它是否是最聪明的方法,如果不是,请建议我。

        我是这样做的:

        class Base{
            SomeBaseFunction();
        
        }
        
        class Derived:public base{
        //I have put a pointer of base type here 
        base *basePointer;
        }
        

        现在在我基本上填充基向量和派生向量的主函数中,我执行以下操作:

        derivedObject->basePointer = baseObject;
        

        现在我可以按如下方式访问基本属性:

        derivedObject->basePointer->SomeBaseFunction();
        

        【讨论】:

        • 在这种情况下,您应该删除:public base。你实际上并没有在你的答案中使用继承,所以如果你在class Derived 之后有:public base,你只会让自己感到困惑。 (如果你不使用继承,你应该将你的类从 Derived 重命名为其他名称)。
        • 感谢您的回答。现在它更有意义了。我还有一个问题,为什么我不应该使用 new 和 *?
        • 在某些情况下new 是必要的,但new 被过度使用。有两个原因。首先,没有new 的代码通常更简单,更易于阅读。您应该对待对象,例如string 或您自己的对象,就像对待int 一样。如果要加5+7,为什么要写int *x = new int(5); int *y = new int(7); int *z = new int(*x+*y);?写int x = 5; int y = 7; int z = x+y 更简单。它还导致更快的代码。最后,如果您使用new,有时您会忘记delete 对象,这会导致错误和内存泄漏。
        • 感谢您的详细解释,但是对于较大的数据集,使用 new 会不会提高内存效率?
        • 我们应该区分“内存效率”和“速度效率”。我建议的方法将不再使用任何内存。是的,有时会复制对象,但会自动删除任何不必要的对象。因此,从长远来看,它不会占用额外的内存。请注意,new 方法将导致内存泄漏,在这种情况下,new 将是低效的方法。至于速度,很容易说我的方法会很慢“因为所有复制大对象”。但是编译器可以优化其中的许多副本(NRVO)。 ...继续
        猜你喜欢
        • 1970-01-01
        • 2017-02-06
        • 2013-03-28
        • 1970-01-01
        • 2021-11-22
        • 2018-01-27
        • 2021-09-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多