提问人:Michael Sipos 提问时间:11/9/2023 最后编辑:wohlstadMichael Sipos 更新时间:11/9/2023 访问量:105
尝试添加带有附加智能指针的矢量
Trying to Add Vectors with Attached Smart Pointers
问:
我正在尝试通过使用智能指针来处理内存管理来提高我的编码技能,并创建了一个简单的程序来添加两个 2D 矢量结构的组件并将其保存到第三个 2D 矢量结构中。
当我调用该函数时,编译器正在爆炸。addVec2()
实际将智能指针(指向实际数据结构而不是基元)传递给函数的例子并不多。
有人可以帮忙解决这个问题吗?
谢谢。
#include <iostream>
#include <memory>
#include <vector>
#define ENDL "\n"
struct vec2
{
int a;
int b;
};
template<typename T>
void addVec2(T *v1, T *v2, T *v3)
{
v3->a = v1->a + v2->a;
v3->b = v1->b + v2->b;
}
int main() {
std::unique_ptr<vec2> p_vec1(new vec2);
p_vec1->a = 1;
p_vec1->b = 2;
std::unique_ptr<vec2> p_vec2(new vec2);
p_vec2->a = 3;
p_vec2->b = 7;
std::unique_ptr<vec2> p_vec3(new vec2);
addVec2<std::unique_ptr<vec2>>(p_vec1, p_vec2, p_vec3);
return 0;
}
我什至尝试使用模板来尝试解决它抱怨只能将类型输入函数而不是仍然指向相同类型()的任何类型的指针的问题,但这仍然不起作用。unique_ptr
vec2
答:
问题:
按值接受参数。但是不可复制的,因此您不能按值传递它们。addVec2
std::unique_ptr
我不建议立即解决的办法可能是通过引用(输入的常量引用)接受参数:
template<typename T>
//-------------vvvvvvv-------vvvvvvv-------v----
void addVec2(T const & v1, T const & v2, T & v3)
{
v3->a = v1->a + v2->a;
v3->b = v1->b + v2->b;
}
但在这种情况下,您实际上并不需要智能指针。
您可以在堆栈上声明对象,并在以下代码中通过引用接受它们:vec2
addVec2
struct vec2
{
int a;
int b;
};
template<typename T>
void addVec2(T const & v1, T const & v2, T & v3)
{
v3.a = v1.a + v2.a;
v3.b = v1.b + v2.b;
}
int main() {
vec2 v1{ 1, 2 };
vec2 v2{ 3, 7 };
vec2 v3;
addVec2(v1, v2, v3);
}
请注意,当我调用时,我没有指定模板参数类型 - 编译可以从参数中推断出来。addVec2
问题似乎是你混淆了智能指针和普通的非拥有非智能指针......
作为参数,编译器和函数需要指向对象的指针。T* v1
std::unique_ptr<vec2>
所以你的电话真的应该是.在函数内部,您需要使用例如,等。addVec2(&p_vec1, &p_vec2, &p_vec3)
(*v1)->a
或者将函数参数更新为引用而不是指针。
评论
std::unique_ptr 无法复制。 因此,您可以使用 std::shared_ptr 而不是 std::unique_ptr
或
template<typename T>
void addVec2(T &v1, T &v2, T &v3)
{
v3->a = v1->a + v2->a;
v3->b = v1->b + v2->b;
}
你正在传递给 ,但它不是 .只需将参数从指针更改为引用即可解决问题。std::unique_ptr
addVec2
T*
addVec2
template<typename T>
void addVec2(T &v1, T &v2, T &v3)
{
v3->a = v1->a + v2->a;
v3->b = v1->b + v2->b;
}
int main() {
// ...
addVec2<std::unique_ptr<vec2>>(p_vec1, p_vec2, p_vec3);
}
但我建议你通过一个,而不是.所以最好写:vec2&
std::unique_ptr<vec2>&
template<typename T>
void addVec2(const T &v1, const T &v2, T &v3)
{
v3.a = v1.a + v2.a;
v3.b = v1.b + v2.b;
}
int main() {
// ...
addVec2(*p_vec1, *p_vec2, *p_vec3);
}
请注意,addVec2 的 type 参数可以推导。并且被添加到和,因为我们不修改它们。const
v1
v2
我不得不四处挖掘,但发现这个教程网站非常有用,它回答了我的问题,足以让我得到一个可用的解决方案,尽管我不知道这是否是“正确”的做事方式。
https://www.learncpp.com/cpp-tutorial/stdunique_ptr/
#include <iostream>
#include <memory>
#include <vector>
#define ENDL "\n"
struct vec2
{
int a;
int b;
};
void addVec2( vec2 *v1, vec2 *v2, vec2 *v3)
{
v3->a = v1->a + v2->a;
v3->b = v1->b + v2->b;
}
int main() {
auto ptr1{ std::make_unique<vec2>() };
ptr1->a = 1;
ptr1->b = 2;
auto ptr2{ std::make_unique<vec2>() };
ptr2->a = 3;
ptr2->b = 7;
auto ptr3{ std::make_unique<vec2>() };
addVec2(ptr1.get(), ptr2.get(), ptr3.get());
std::cout << ptr3->a << "," << ptr3->b << ENDL;
return 0;
}
评论
上一个:析构函数意外调用
评论
std::unique_ptr
不可复制,因此不能按值将其传递给 。但在这种情况下,你根本不需要智能指针 - 只需在堆栈上声明对象并提出接受参数即可。addVec2
vec2
addVec2
T&
addVec2<std::unique_ptr<vec2>>(p_vec1, p_vec2, p_vec3)
addVec2(p_vec1, p_vec2, p_vec3)
vec2 operator+(vec2 const&, vect2 const&);
<unique_ptr<T>>
unique_ptr
get()
std::make_unique
new