gpt4 book ai didi

c++ - STL vector 上的奇怪复制构造函数错误

转载 作者:搜寻专家 更新时间:2023-10-31 00:52:30 24 4
gpt4 key购买 nike

因此,我目前正在完成我的物理引擎,但我无法弄清楚某个类有什么问题,以及为什么编译器报告它的复制构造函数在使用 vector 时被删除了。


这是我的类(class)

const real baumgarteCoef = 0.5f;
// based on GoblinPhysics'
// https://github.com/chandlerprall/GoblinPhysics/blob/master/src/classes/Constraints/ContactConstraint.js
class ContactConstraint : public Constraint {
public:
ContactConstraint(PhysicalObject* objA, PhysicalObject* objB, const Vector3& position,
const Vector3& normal, real penetration)
: Constraint(objA, objB, (u32)1) {
collisionPosition = position;
collisionNormal = normal;
this->penetration = penetration;
real r1 = objA->getRestitution();
real r2 = objB->getRestitution();
restitutionCoef = Math::SquareRoot(r1 * r2);
rows[0].lowerLimit = 0.f;
rows[0].upperLimit = Math::PositiveInfinity;
collisionPosA = objA->getInverseRotation().rotate(position - objA->getPosition() +
normal * penetration);
collisionPosB = objB->getInverseRotation().rotate(position - objB->getPosition() -
normal * penetration);
}

ContactConstraint(const ContactConstraint& c) = default;

void update(real timeElapsed) {
auto& row = rows[0];

if (objA->isStatic()) {
row.jacobian[0] = 0.f;
row.jacobian[1] = 0.f;
row.jacobian[2] = 0.f;
row.jacobian[3] = 0.f;
row.jacobian[4] = 0.f;
row.jacobian[5] = 0.f;
} else {
row.jacobian[0] = -collisionNormal.x();
row.jacobian[1] = -collisionNormal.y();
row.jacobian[2] = -collisionNormal.z();

Vector3 v = collisionPosition - objA->getPosition();
Vector3 v2 = v.cross(collisionNormal);
row.jacobian[3] = -v2.x();
row.jacobian[4] = -v2.y();
row.jacobian[5] = -v2.z();
}

if (objB->isStatic()) {
row.jacobian[6] = 0.f;
row.jacobian[7] = 0.f;
row.jacobian[8] = 0.f;
row.jacobian[9] = 0.f;
row.jacobian[10] = 0.f;
row.jacobian[11] = 0.f;
} else {
row.jacobian[6] = collisionNormal.x();
row.jacobian[7] = collisionNormal.y();
row.jacobian[8] = collisionNormal.z();

Vector3 v = collisionPosition - objB->getPosition();
Vector3 v2 = v.cross(collisionNormal);
row.jacobian[9] = v2.x();
row.jacobian[10] = v2.y();
row.jacobian[11] = v2.z();
}

// Apply penetration error.
row.bias = baumgarteCoef * penetration / timeElapsed;
// Apply restitution
Vector3 velocity = objA->getLinearVelocity() +
collisionPosA.cross(objA->getAngularVelocity()) -
objB->getLinearVelocity() - collisionPosB.cross(objB->getAngularVelocity());
real restitution = (collisionNormal.dot(velocity)) * restitutionCoef;
row.bias += restitution;
}

private:
Vector3 collisionPosition;
Vector3 collisionNormal;
Vector3 collisionPosA;
Vector3 collisionPosB;
real penetration;
real restitutionCoef;
};

及其父类

// based on GoblinPhysics'
// https://github.com/chandlerprall/GoblinPhysics/blob/master/src/classes/Constraints/ConstraintRow.js
class Constraint {
public:
class Row {
public:
Constraint* parent;
real jacobian[12];
real derivedMass[12];
real effectiveMass;
real lowerLimit;
real upperLimit;
real bias;
real multiplier;
real multiplierCache;
real eta;

void computeDerivedMass();
void computeEffectiveMass();
void computeEta(real timeDelta);
};

Constraint(PhysicalObject* objectA, PhysicalObject* objectB, u32 numRows) {
objA = objectA;
objB = objectB;
rows = std::make_unique<Row[]>(numRows);
this->numRows = numRows;
for (u32 i = 0; i < numRows; i++)
rows[i].parent = this;
breakingThreshold = 0.f;
active = true;
}

Constraint(const Constraint& c) = default;
PhysicalObject* objA;
PhysicalObject* objB;
std::unique_ptr<Row[]> rows;
Vector3 lastImpulse;
u32 numRows;
real breakingThreshold;
bool active;

virtual void update(real timeElapsed) = 0;
};

错误(上帝保佑,因为编译器可以压缩它)

[  9%] Building CXX object src/CMakeFiles/kepler3d.dir/PhysicsEngine/PhysicsEngine.cpp.obj
In file included from D:/msys64/mingw64/include/c++/7.3.0/memory:64:0,
from D:/msys64/home/ferna/Kepler3D/src/Architecture/Command.h: ,
from D:/msys64/home/ferna/Kepler3D/src/Architecture/Architecture.h:3,
from D:/msys64/home/ferna/Kepler3D/src/PhysicsEngine/PhysicsEngine.cpp:2:
D:/msys64/mingw64/include/c++/7.3.0/bits/stl_construct.h: In instantiation of 'void std::_Construct(_T1*, _Args&& ...) [with _T1 = Kepler3D::ContactConstraint; _Args = {Kepler3D::ContactConstraint}]':
D:/msys64/mingw64/include/c++/7.3.0/bits/stl_uninitialized.h:83:18: required from 'static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<Kepler3D::ContactConstraint*>; _ForwardIterator = Kepler3D::ContactConstraint*; bool _TrivialValueTypes = false]'
D:/msys64/mingw64/include/c++/7.3.0/bits/stl_uninitialized.h:134:15: required from '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<Kepler3D::ContactConstraint*>; _ForwardIterator = Kepler3D::ContactConstraint*]'
D:/msys64/mingw64/include/c++/7.3.0/bits/stl_uninitialized.h:289:37: required from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator<Kepler3D::ContactConstraint*>; _ForwardIterator = Kepler3D::ContactConstraint*; _Tp = Kepler3D::ContactConstraint]'
D:/msys64/mingw64/include/c++/7.3.0/bits/stl_uninitialized.h:311:2: required from '_ForwardIterator std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = Kepler3D::ContactConstraint*; _ForwardIterator = Kepler3D::ContactConstraint*; _Allocator = std::allocator<Kepler3D::ContactConstraint>]'
D:/msys64/mingw64/include/c++/7.3.0/bits/vector.tcc:426:6: required from 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {Kepler3D::PhysicalObject*&, Kepler3D::PhysicalObject*&, const Kepler3D::Vector3&, const Kepler3D::Vector3&, float&}; _Tp = Kepler3D::ContactConstraint; _Alloc = std::allocator<Kepler3D::ContactConstraint>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<Kepler3D::ContactConstraint*, std::vector<Kepler3D::ContactConstraint> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = Kepler3D::ContactConstraint*]'
D:/msys64/mingw64/include/c++/7.3.0/bits/vector.tcc:105:21: required from 'std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {Kepler3D::PhysicalObject*&, Kepler3D::PhysicalObject*&, const Kepler3D::Vector3&, const Kepler3D::Vector3&, float&}; _Tp = Kepler3D::ContactConstraint; _Alloc = std::allocator<Kepler3D::ContactConstraint>; std::vector<_Tp, _Alloc>::reference = Kepler3D::ContactConstraint&]'
D:/msys64/home/ferna/Kepler3D/src/PhysicsEngine/Dynamics/ConstraintsManager.h:23:82: required from here
D:/msys64/mingw64/include/c++/7.3.0/bits/stl_construct.h:75:7: error: use of deleted function 'Kepler3D::ContactConstraint::ContactConstraint(const Kepler3D::ContactConstraint&)'
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }

我不确定父类上的唯一指针是否导致无法派生复制构造函数。我还想补充一点,在任何情况下我都不会直接复制类(仅放置),但是,由于 vector 类的内部机制,复制是默认的。


此行导致 ConstraintsManager 中的错误

contactConstraints.emplace_back(objA, objB, position, normal, penetration);

最佳答案

无法复制包含 unique_ptr 的对象,因为该成员(即 rows)默认情况下不可复制。如果您需要复制,您必须提供自己的实现。

据我所知,通过查看错误跟踪,我认为您应该能够移动对象。您是否尝试提供默认移动构造函数?

Constraint(Constraint&& c) = default;

我认为它也需要是 noexcept

我不确定是否可以复制和/或移动您的派生类,因为我没有 Vector3 的定义。

很明显,从错误跟踪中可以看出,您需要能够复制(或移动)项目,因为在 vector 已满时添加项目时可能需要调整其大小。

虽然,我相信在这个例子中你需要深拷贝,在某些情况下,你可以存储 shared_ptr 而不是 unique_ptr 然后你会有一个浅拷贝构造函数自动生成。

如果事实上,它也可能在这里工作,但您需要小心不要意外复制然后修改对象,而没有意识到数据在这些对象之间部分共享。

关于c++ - STL vector 上的奇怪复制构造函数错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51487976/

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