在 C++ 中将派生类类型的向量链接到父类类型的向量

Posted

技术标签:

【中文标题】在 C++ 中将派生类类型的向量链接到父类类型的向量【英文标题】:linking vector of derived class type to vector of parent class type in 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:我基本上想在派生对象中保留一些指针,以便它们可以指向基础对象。 您关于对象、指针和向量(基数、派生数)的话很复杂。 【参考方案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)。 ...继续

以上是关于在 C++ 中将派生类类型的向量链接到父类类型的向量的主要内容,如果未能解决你的问题,请参考以下文章

从基类类型的向量访问派生类方法

如何在 SWIG 中将向量的锯齿状 C++ 向量转换(类型映射)为 Python

赋值兼容原则

C++学习摘要之三:继承和派生

c++ 虚函数 如何调父类 而非子类

c ++如何按类类型对向量进行排序