c++ 尝试添加带有智能指针的向量

1aaf6o9v  于 2023-11-19  发布在  其他
关注(0)|答案(5)|浏览(104)

我试图通过使用智能指针来处理内存管理来提高我的编码技能,并创建了一个简单的程序来添加两个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),但这仍然不工作。

yquaqz18

yquaqz181#

你将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的类型参数可以推导出来。并且const被添加到v1v2中,因为我们没有修改它们。

agxfikkp

agxfikkp2#

问题似乎是你混淆了智能指针和普通的非拥有的非智能指针。
作为参数T* v1,编译器和函数需要一个指向std::unique_ptr<vec2>对象的 * 指针 *。
所以你的调用实际上应该是addVec2(&p_vec1, &p_vec2, &p_vec3)。在函数内部你需要使用例如(*v1)->a等。
或者将函数参数更新为 references 而不是指针。

vc9ivgsu

vc9ivgsu3#

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;
}

字符串

atmip9wb

atmip9wb4#

我不得不四处挖掘,但发现这个教程网站非常有用&它回答了我的问题,足以让我得到一个可用的解决方案,虽然我不知道这是否是“正确”的方式做事情。
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;
}

字符串

z6psavjg

z6psavjg5#

问题:
addVec2通过值接受参数。但是std::unique_ptr不可复制的,所以不能通过值传递参数。
一个我不推荐的立即修复方法是接受参数by reference(输入的const reference):

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时,我没有指定模板参数类型-编译器可以从参数中推导出它。

相关问题