vector<unique_ptr<T> > 作为基类成员

Posted

技术标签:

【中文标题】vector<unique_ptr<T> > 作为基类成员【英文标题】:vector< unique_ptr<T> > as base class member 【发布时间】:2014-06-11 21:12:53 【问题描述】:

我有三个班级:

Class Something
...

Class A

public:
    A();
    virtual ~A() = 0; //have also tried this as non-abstract

    std::vector< unique_ptr<Something> > somethings; //have tried this just as std::vector<Something*> as well
;

class B : public A

    B();
    ...

如果我从 B 类中省略 std::vector somethings 的声明...那么我的编译器会告诉我类“B”没有任何名为“somethings”的字段。

所以如果我重新添加它,我会尝试像这样引用它

A *a = new B();

for(auto it = a->somethings.begin(); it != a->somethings.end(); it++)

     Draw((*it)->image,(*it)->x, (*it)->y, NULL, (*it)->angle);

它说 a->somethings 是空的......即使我从 B 本身打印来告诉我有多少“东西”,它也准确地报告了计数。这就是导致我删除 std::vector somethings; 的原因。从 B 类开始,因为我怀疑它以某种方式获取了 A 的向量,即使它是抽象的。

奖励:如果我去 B *b = new B(); 这一切都有效当我添加父类 A 并让 B 从它继承时刚刚坏了。

【问题讨论】:

somethings 是私有的... @DrewDormann somethings 在我的代码中是公开的,就像 B : public A 一样,但我觉得它偏离了包含的意义。编辑:为了清楚起见,我已将其包括在内。这也很重要,因为 Draw 函数访问成员 something。 coliru.stacked-crooked.com/a/c2913bfcccbe407d - 我已经编译了一个例子 B类也有“东西”吗?如果是这样发布完整的代码 @zmartin 请在您的问题中发布真实代码。您问题中的代码没有出现您描述的问题。 【参考方案1】:

从您评论中的链接代码来看,问题在于您试图直接在派生类中初始化基类字段。由于基类字段是由基类构造函数初始化的,因此您不能这样做(尝试也没有意义)。如果要初始化字段(而不是赋值给它),需要在基类构造函数中进行:

class Base 
public:
    std::vector<float> fVec;
    Base(std::vector<float> v) : fVec(v)  
;

class Derived : public Base 
public:
    Derived(std::vector<float> v) : Base(v) 
        :

请注意,您在上面显示的代码与您链接的代码完全不同且无关 - 您应该发布与您的问题相关的代码,而不是不相关的不相关代码。

【讨论】:

已添加代码,用于响应 - 我链接的代码的要点是生成的错误 - 无论是否在构造函数中初始化,派生类都不拥有 std::vector fVec。如果将它从构造函数移到让 Dervied 自己填充它,则错误是相同的。 什么都没有,现在?每个人都这么快地看了一眼我的代码,批评了它,却没有提供任何有价值的东西。您的答案仍然无效,而且我没有在任何地方初始化基类的值。我关心派生类的向量,我初始化它并在类中填充它。我在课堂外通过带有 Weapon * mainWep = new BowAndArrow(); 的绘图函数访问它。我应该收回我的反对票 =/ 你甚至没有费心去阅读我链接的页面上的编译器输出。 @zmartin:派生类可以访问基类中的字段(除非您将其设为私有),因此它不需要(也不应该拥有)自己的字段。你显示的错误出现的唯一方法是incorrectly attempt to initialize the field in the derived class,这可以像我在这里展示的那样修复。您显示的其他代码根本没有任何明显的错误...... 感谢您的回复。该代码仍然会产生相同的错误,经过数小时的处理并构建一个产生相同结果的测试示例后,我放弃并废弃它,就像这篇文章一样。谢谢!【参考方案2】:

我不确定这是否会对您有所帮助,但我对您的 coliru.stacked-crooked 示例进行了一些小改动,如下所示:

#include <vector>

class Base

public:
    std::vector<float> fVec;
;

class Derived : public Base

public:
    Derived(std::vector<float> v) // : fVec(v)
    
        fVec = v;
    
;
int main() 

请注意,我从构造函数初始化列表中注释掉了fVec,并将其分配到构造函数的主体中。这里的问题是,在您输入 Derived 构造函数主体的左大括号之前,您的 Base 对象尚未完全创建。

要解决此问题,您可以向您的 Base 对象添加一个构造函数,该对象接受一个向量,然后将其分配给您的对象,或多或少是 Chris 所说的。

以上两个示例都适用于我,但我没有您的完整代码,因此无法确定它们是否能解决您的所有问题。我想我还是要赌一把。

您可能对正在制作的向量副本了如指掌,应该将它们作为 const refs 传递,但这是另一个问题。

【讨论】:

以上是关于vector<unique_ptr<T> > 作为基类成员的主要内容,如果未能解决你的问题,请参考以下文章

调整 std::vector<std::unique_ptr<T>> 大小的性能

boost::ptr_vector 与 std::vector<std::unique_ptr<T>>? [关闭]

vector系列--vector<unique_ptr<;;初始化(所有权转移)

vector<unique_ptr> 的初始化失败并出现复制错误

使用 C++11 for() 循环遍历 vector<unique_ptr<mytype>>

如何调整 std::vector<std::queue<std::unique_ptr<int>>> 的大小?