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
所以如果我重新添加它,我会尝试像这样引用它
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> 的初始化失败并出现复制错误