Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 虚拟函数如何影响OpenGL中点的生成方式?_C++_Opengl - Fatal编程技术网

C++ 虚拟函数如何影响OpenGL中点的生成方式?

C++ 虚拟函数如何影响OpenGL中点的生成方式?,c++,opengl,C++,Opengl,我有一个项目,我用点画了一个三角形,它叫做Sierpinski垫圈。为了实现这一点,我使用了一个Vx类来保存x和y值。问题是,如果任何方法是虚拟的,它会抛出不同的值,我想知道为什么虚拟函数如何影响在以下OpenGL代码中生成点的方式? 我的vector类具有以下声明: class Vx { public: float x; float y; Vx(); Vx(const float& value); Vx(const float&

我有一个项目,我用点画了一个三角形,它叫做Sierpinski垫圈。为了实现这一点,我使用了一个Vx类来保存x和y值。问题是,如果任何方法是虚拟的,它会抛出不同的值,我想知道为什么虚拟函数如何影响在以下OpenGL代码中生成点的方式?

我的vector类具有以下声明:

    class Vx {
public:
    float x;
    float y;

    Vx();
    Vx(const float& value);
    Vx(const float& x, const float& y);
    Vx(const Vx& v);

    float getX() const;
    void setX(const float& x);
    float getY() const;
    void setY(const float& y);

    const float operator [] (int i) const;
    operator const float* () const;
    operator float* ();
    float& operator [] (int i);
};

std::ostream& operator<<(std::ostream& os, const Vx v);

Vx operator+(const Vx& p1, const Vx& p2);

Vx operator/(const Vx& p1, const Vx& p2);
Vx类{
公众:
浮动x;
浮动y;
Vx();
Vx(常数浮点和值);
Vx(常数浮点和x、常数浮点和y);
Vx(常数Vx&v);
float getX()常量;
无效设置x(常数浮动和x);
float getY()常量;
void setY(常数浮动&y);
常量浮点运算符[](int i)常量;
运算符常量浮点*()常量;
运算符浮点*();
浮点和运算符[](int i);
};

std::ostream&operator具有虚拟方法的类具有指向
VMT
(虚拟方法表)的隐式字段指针。您可以通过打印
sizeof(Vx)
来检查它,可以使用虚拟方法,也可以不使用虚拟方法。类和结构的内部表示没有被C++标准指定,并且在编译器之间有所不同,因此,不应将类方法与虚拟方法传递给函数,如“代码> GLBuffelDATABOS/CODE”。

< P>类,用虚方法具有隐式字段指针,指向“代码> VMT < /COD>(虚方法表)。您可以通过打印
sizeof(Vx)
来检查它,可以使用虚拟方法,也可以不使用虚拟方法。类和结构的内部表示没有被C++标准指定,编译器之间也有不同,因此,在某些研究之后,不应该将类方法与虚拟方法传递到诸如“代码> GLPuffelDATABOS/COD>”之类的函数。我发现了这个问题的更详细的答案,因为它解释了为什么虚拟函数影响类成员有不同的内存分配,导致不同的结果,此外还有一些C++引用的文档,这些文档也解释了多态对象和内存分配。 事实上,这是一种未定义的行为,下面问题的答案用一种简短而更好的方式解释了原因

<> P>还想从下面2个链接中添加C++引用的内容:

我们可以从以下位置找到下一个文档:

多态对象:声明或继承的类类型的对象 至少有一个虚拟函数是多态对象。在每个 多态对象,实现存储附加信息 (在每个现有实现中,除非经过优化,否则它是一个指针 out),它由虚拟函数调用和RTTI功能使用 (dynamic_cast和typeid)在运行时使用 无论使用的是哪种表达式,都是创建对象的对象 在里面对于非多态对象,值的解释是 根据使用对象的表达式确定,并且 在编译时决定

内存位置:内存位置是标量类型的对象 (算术类型、指针类型、枚举类型或std::nullptr\t) 或长度非零的位字段的最大连续序列 注意:语言的各种特性,例如引用和虚拟 函数,可能涉及不可用的其他内存位置 可供程序访问,但由实施部门管理


考虑到所有这些,我们可以更详细地了解使用虚拟函数的未定义行为的来源,了解它们在生成点时如何改变行为。

经过一些研究,我发现了这个问题的更详细的答案,因为它解释了为什么虚拟函数影响类成员有不同的内存分配,导致不同的结果,此外还有一些C++引用的文档,这些文档也解释了多态对象和内存分配。 事实上,这是一种未定义的行为,下面问题的答案用一种简短而更好的方式解释了原因

<> P>还想从下面2个链接中添加C++引用的内容:

我们可以从以下位置找到下一个文档:

多态对象:声明或继承的类类型的对象 至少有一个虚拟函数是多态对象。在每个 多态对象,实现存储附加信息 (在每个现有实现中,除非经过优化,否则它是一个指针 out),它由虚拟函数调用和RTTI功能使用 (dynamic_cast和typeid)在运行时使用 无论使用的是哪种表达式,都是创建对象的对象 在里面对于非多态对象,值的解释是 根据使用对象的表达式确定,并且 在编译时决定

内存位置:内存位置是标量类型的对象 (算术类型、指针类型、枚举类型或std::nullptr\t) 或长度非零的位字段的最大连续序列 注意:语言的各种特性,例如引用和虚拟 函数,可能涉及不可用的其他内存位置 可供程序访问,但由实施部门管理


考虑到所有这些因素,我们可以更详细地了解使用虚拟函数的未定义行为的来源,了解它们在生成点时如何改变行为。

虚拟
函数不太可能是问题所在,考虑到您显示的代码,因为您似乎没有使用任何间接寻址(例如,通过指向基的指针或引用调用派生类的函数)。更可能的问题是,您将
x
y
成员视为数组的一部分,而它们不是数组的一部分,这将导致未定义的行为。我建议去掉
operator[]
operator float*Vectors::Vx::Vx() : x(0), y(0)
{
}

Vectors::Vx::Vx(const float& value) : x(value), y(value)
{
}

Vectors::Vx::Vx(const float& x, const float& y) : x(x), y(y)
{
}

Vectors::Vx::Vx(const Vx& v) : x(v.x), y(v.y)
{
}

float Vectors::Vx::getX() const
{
    return this->x;
}

void Vectors::Vx::setX(const float& x)
{
    this->x = x;
}

float Vectors::Vx::getY() const
{
    return this->y;
}

void Vectors::Vx::setY(const float& y)
{
    this->y = y;

}

float& Vectors::Vx::operator[](int i)
{
    return *(&x + i);

}

const float Vectors::Vx::operator[](int i) const
{
    return *(&x + i);
}

Vectors::Vx::operator const float* () const
{
    return static_cast<const float*>(&x);
}

Vectors::Vx::operator float* ()
{
    return static_cast<float*>(&x);

}

std::ostream& Vectors::operator<<(std::ostream& os, const Vx v)
{
    os << "Vx: " << "x = " << v.x << ", y = " << v.y << std::endl;
    return os;
}

Vx Vectors::operator+(const Vx& p1, const Vx& p2)
{
    return Vx(p1.x + p2.x, p1.y + p2.y);
}

Vx Vectors::operator/(const Vx& p1, const Vx& p2)
{
    return Vx(p1.x / p2.x, p1.y / p2.y);
}
void sierpinskiGasket() {

using namespace Vectors;

/*
Creamos la informacion para el triangulo
*/
const int numPoints = 5000;
Vx points[numPoints];
points[0] = Vx(0.0f, 0.0f);

Vx vertices[] = {
    Vx(-0.50f, -0.50f),
    Vx(0.50f, -0.50f),
    Vx(0.0f, 0.50f)
};

for (int i = 1; i < numPoints;i++) {
    int j = rand() % 3;

    points[i] = (points[i - 1] + vertices[j]) / 2;
}

/*
    Generamos el buffer para el triangulo
*/
unsigned int triangle_vbo;
glGenBuffers(1, &triangle_vbo);
glBindBuffer(GL_ARRAY_BUFFER, triangle_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
}