当我在 if 语句中返回对象的新实例时调用析构函数

问题描述 投票:0回答:1
class Vec
{
public:
    unsigned int dim;
    float* elements;

    // Constructors
    Vec() : dim(0), elements(nullptr) {}

    Vec(unsigned int dim, ...) : dim(dim), elements(new float[dim])
    {
        va_list args;
        va_start(args, dim);

        for (unsigned int i = 0; i < dim; i++)
        {
            // C/C++ promotes floats passed as variable arguments to double,
            // so you need to use va_arg(args, double) and cast it to float
            elements[i] = static_cast<float>(va_arg(args, double));
        }

        va_end(args);
    }

    Vec(unsigned int dim, float value) : dim(dim), elements(new float[dim])
    {
        for (unsigned int i = 0; i < dim; i++)
        {
            elements[i] = value;
        }
    }

    // Destructor
    ~Vec()
    {
        delete[] elements;
    }
};


Vec vecAdd(Vec* v1, Vec* v2)
{
    if (v1->dim != v2->dim)
    {
        //Vec VEC_UNDEFINED;
        //return VEC_UNDEFINED;
        return Vec;
    }

    Vec ret(v1->dim);

    for (unsigned int i = 0; i < ret.dim; i++)
    {
        ret.elements[i] = v1->elements[i] + v2->elements[i];
    }

    return ret;
}

如果我调用该类并将向量添加到一起并返回 ret 对象,则会调用析构函数,并且所有 ret.elements 都会被删除,这是我不想要的。

如果我注释掉“return Vec;”在我的边界检查中并取消注释“//Vec VEC_UNDEFINED; //return VEC_UNDEFINED;”析构函数不会被调用,并且代码按预期工作。为什么 C++ 会这样?

c++ destructor
1个回答
0
投票

您可以使用模板改进您的代码(假设您的向量维度是固定的,这似乎根据您的代码有意义)它看起来像这样(否则只需使用 std::vector 或包装它)

#include <array>
#include <algorithm>
#include <iostream>

template<std::size_t dim_v>
class Vec final
{
public:
    explicit Vec(const float(&values)[dim_v]) 
    {
        std::copy(std::begin(values),std::end(values),m_values.begin());
    }

    explicit Vec(float value)
    {
        std::fill(m_values.begin(), m_values.end(), value);
    }

    // Destructor
    ~Vec() = default;

    const auto& values() const noexcept
    {
        return m_values;
    }

    constexpr auto& dims() const noexcept
    {
        return dim_v;
    }

private:
    std::array<float, dim_v> m_values;
};

int main()
{
    Vec v{ {0.f,1.f,2.f} };

    for (const auto& value : v.values())
    {
        std::cout << value << "\n";
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.