gpt4 book ai didi

c++ - 包含多态对象的 vector : static assertion error

转载 作者:行者123 更新时间:2023-11-30 03:26:54 24 4
gpt4 key购买 nike

自从大学以来就没有使用过 C++,我尝试使用具有 2 种类型的子对象的 vector ,但显然我遇到了一些错误。

最初我使用了一个指针 vector ,它起作用了,但如果我理解正确的话,它会在清除时泄漏内存。

我遇到的错误让我相信它与类中的静态计数器有关(被最后一个成员破坏了?),但删除它并没有解决它。

错误导致此处,在 STL_construct.h 中:

#if __cplusplus >= 201103L
// A deleted destructor is trivial, this ensures we reject such types:
static_assert(is_destructible<_Value_type>::value,
"value type is destructible");
#endif

好吧,但是我的析构函数都是显式声明的。我记得父类应该使用虚拟析构函数并修复了它,但问题仍然存在。

将构造函数/析构函数移至虚拟父类的 public 不应该(实际上也没有)改变一些事情。

现在我假设我以某种方式滥用了 vector 。这是我的例子:

主要内容:

#include <stdio.h>
#include "Foo.h"
#include <iostream>
Bar buildBar();

int main(int argc, char **argv)
{
std::vector<Foo> Foos;
Foos.reserve(1);
Foos.push_back(buildBar());
for (int idx=(0);sizeof(Foos);idx++)
{
try {
std::cout << "x = " << Foos.at(idx).getLoc().at(0);
}
catch (std::exception& e) {
std::cout << idx << ": Index out of range" << std::endl;
}
}
Foos.clear();
return 0;
}

Bar buildBar()
{
Bar* temp = new Bar(5,6);
return *temp;
}

Foo.h,构造函数移至标题:

#ifndef FOO_H
#define FOO_H
#include <vector>
class Foo
{
public:
//int maxoID(){return lastoID;} //0-indexed
/* Other things */
virtual std::vector<int> getLoc(){ return {x_Base,y_Base};}
Foo():
//oID(-1),
x_Base(-1),
y_Base(-1){}
virtual ~Foo(){}
protected:
int x_Base;
int y_Base;
};

class Bar : public Foo
{
public:
Bar(int x1, int y1):
x_End(-1),
y_End(-1)
{
x_Base = x1;
y_Base = y1;
}
~Bar(){}
std::vector<int> getLoc() {return {x_Base,y_Base,x_End,y_End};}
protected:
int x_End;
int y_End;

};

#endif // FOO_H

最佳答案

首先,感谢您质疑您对原始指针的使用!人们往往只是盲目地使用它们,最终会导致其他问题。

您当前的问题是您有 object slicing .当您插入 Bar进入 vector<Foo>您丢失了有关 Bar 的重要信息.如果你调用一个只接受 Foo 的函数,也会发生同样的情况。 , 不是 Foo&Foo* .

根据您的用途,您可以使用 std::unique_ptr , std::shared_ptr , 或 std::reference_wrapper

请注意,您可以使用原始指针,它们不仅会自动泄漏内存,而且 vector不会对内存负责(这是我指出的使用智能指针之一的好处)

这是完全可以接受的:

int main()
{
Foo* f = new Foo;
{
std::vector<Foo*> v;
v.push_back(f);
} // v goes out of scope and is cleaned up
delete f; // the vector won't have cleaned this up, it's our responsibility
}

使用 unique_ptr相反只是让这一切变得不那么复杂。当然,在这样一个简单的示例中,原始指针很容易使用,但在更大的程序中它可能会失控:

另请注意,如@juanchopanza points out in the comments , 你的 buildBar函数泄漏内存。当你打电话时

return *temp;

您创建一个拷贝,您将丢失 temp 的内存地址因此无法删除它。

Bar buildBar()
{
Bar* temp = new Bar(5,6);
return *temp;
}

Bar b = buildBar();
Bar* p = &b; // this only reference the copy, b
delete p; // this is bad, this will (double) delete the memory from b, which is not the same as temp.

b当它超出范围时将被自动清理(如果您也尝试删除它,这很糟糕),但您无法删除 temp

关于c++ - 包含多态对象的 vector : static assertion error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47862695/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com