在构造函数中初始化变量?

时间:2020-06-08 15:32:07

标签: c++ inheritance vector std glfw

我正在尝试将带有矢量的对象设置为成员字段。我设置了构造函数,据我所知确实确实初始化了该成员变量,但是尝试访问向量时会遇到错误,除非在对象的函数调用中对其进行了初始化。我收到警告说

C26495: Variable 'Engy::Graphics::Shape2D::m_vertices' is uninitialized. Always initialize a member variable (type.6).

问题是,我确实在构造函数中对其进行了初始化。我想念什么重要的东西吗?这是我的代码:

类声明(头文件)

class Shape2D:Object
        {
            protected:
                std::vector<Vector> *m_vertices;
                int type = GL_QUADS;
            public:
                Shape2D(std::vector<Vector> vertices);
                Shape2D();
                void draw();
                void setVector(int index, Vector value);
                Vector getVector(int index);
                void translate(double x, double y);
                void createVector(int i, double x, double y);
                void createVector(double x, double y);
                void addVector(Vector value);
        };

方法声明(.cpp文件)

Shape2D::Shape2D(std::vector<Vector> vertices)
{
    std::vector<Vector> m_vertices = vertices;
}
Shape2D::Shape2D()
{
    std::vector<Vector> *m_vertices = new std::vector<Vector>;
}

void Shape2D::setVector(int index, Vector value)
{
    //THIS PART RIGHT HERE IS WHAT I HAVE TO DO TO MAKE IT NOT CRASH, BUT I DONT WANT TO HAVE TO PUT THIS EVERYWHERE
    if (!m_vertices)
    {
        m_vertices = new std::vector<Vector>;
    }
    if (m_vertices->size() < index)
    {
        m_vertices->assign(index - m_vertices->size(), NULL);       
    }
    m_vertices->at(index) = value;
}

对象创建

    //Rectangle is a subclass of Shape2D which calls the default constructor of Shape2D then runs calls to add the constructor inputs in (Let me know if you would like to see that code)
    Rectangle r(0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.0, 0.5);

谢谢你们!

4 个答案:

答案 0 :(得分:5)

std::vector<Vector> m_vertices = vertices;

不初始化成员变量。它将初始化具有相同名称的函数局部变量。函数局部变量隐藏/隐藏成员变量。

最佳做法是使用member-initialization-list语法初始化成员。

Shape2D::Shape2D(std::vector<Vector> vertices) : m_vertices(vertices)
{
}

这将需要对您的班级进行一次更改。您需要将m_vertices更改为矢量对象,而不是指针。

std::vector<Vector> m_vertices;

那是个好习惯。

答案 1 :(得分:2)

  1. 您要在构造函数中定义和初始化一个名为m_vertices的局部变量,而不是类的成员变量。
  2. 您不应使用指针,也不要使用newdelete-成员向量由类实例“拥有”。

...以及其他答案建议根据这些更正进行类设计(例如@RSahu的答案)。但是-仍然有问题。对我来说,您不希望能够对形状的顶点进行完全的编辑控制,而另一方面却要保护顶点矢量是没有意义的。同样,形状也不希望增长,增长和增长。所以我会建议完全其他的东西:

class Shape2D : Object {
public:
    using vertex_type = Vector;
    using vertices_type = std::vector<vertex_type>;
protected:
    const vertices_type m_vertices;
public:
    Shape2D() = delete;
    Shape2D(vertices_type vertices) : m_vertices(std::move(vertices)) { }
    Shape2D(const Shape2D& shape) = default;
    Shape2D(Shape2D&& shape) = default;

    // other methods here, but -  no methods for editing vertices!
}

现在,就顶点而言,形状(基本上)是不可变的。要改变形状吗?创建一个新的形状对象。

或者,如果您必须具有对顶点的编辑权限(我对此表示怀疑),请考虑通过访问器方法(在m_vertices或子类中公开Shape2D ,例如EditableShaped2D

vertices_type& EditableShape2D::vertices() { return m_vertices; }

并不是您遇到的所有麻烦。

答案 2 :(得分:1)

在此构造函数中:

Shape2D::Shape2D()
{
    std::vector<Vector> *m_vertices = new std::vector<Vector>;
}

您要声明一个单独变量m_vertices,因此成员变量永远不会初始化。

相反,您应该简单地做:

Shape2D::Shape2D()
{
   m_vertices = new std::vector<Vector>;
}

但是,您应该使用成员初始化程序列表来初始化成员,如下所示:

Shape2D::Shape2D() : m_vertices {new std::vector<Vector>} {}

请注意,您的单个构造函数参数也需要修复。由于类型不匹配,将导致错误。您也可以通过在其中分配内存来解决此问题。

话虽如此,我建议您重新考虑设计,以查看您是否可以完全避免进行手动内存管理。例如您尚未定义析构函数,因此您将泄漏内存。另外,您将需要自己实现复制构造函数等。

答案 3 :(得分:1)

在默认构造函数中:

Shape2D::Shape2D()
{
    std::vector<Vector> *m_vertices = new std::vector<Vector>;
}

您定义了一个名称为m_vertices的全新变量,该变量与具有相同名称的Shape2D成员变量不同且独立。此局部变量 shadow 成员变量。

您可以使用成员初始化程序列表来解决该问题:

Shape2D::Shape2D()
    : m_vertices{ new std::vector<Vector> }
{
}

在另一个构造函数中,您也遇到类似的问题,但问题也有所不同:参数不是指针,并且您无法使m_vertices指向该参数。解决方案是完全不使用指针作为向量。您几乎永远不需要指向容器的指针。

实际上,这两个问题的解决方案只是将类中的m_vertices声明为普通对象,而不是指针:

class Shape2D
{
    std::vector<Vector> m_vertices;  // Not a pointer
    ...
};
相关问题