C 将指针的阵列运行

C++ passing array of pointers to function

本文关键字:阵列 运行 指针      更新时间:2023-10-16

我在将指针数组传递给函数时有问题。

class ctree01是CdecorationObj的孩子。当我用于循环时,它可以正常工作。

这是我的代码:

CTree01 *trees01;
int numTree01 = ...;
trees01 = new CTree01[numTree01];
//main loop
for(int i=0;i<numTree01;i++)
    {
        {
            //Everything is working okay here, renders all trees
            glPushMatrix();
            trees01[i].DrawOnTerrain(camera);
            glPopMatrix();
        }
    }

,但是由于我替换了一个功能,因此它不再起作用:

void DrawDecorationType(CDecorationObj* objs, int number, CCamera *camera)
{
    int x,z;
    for(int i=0;i<number;i++)
    {
        {
            glPushMatrix();
            objs[i].DrawOnTerrain(camera);
            glPopMatrix();
        }
    }
}
//main loop
DrawDecoration(trees01, numTree01, camera);

当我在该功能中执行时:

objs[0].DrawOnTerrain(camera);

它有效,并且仅当我用索引> 0渲染对象时才崩溃,所以我认为将参数传递给函数必须是问题。

让我看看我是否可以使用几个简单类解释问题。

假设您有:

struct Foo
{
   char a;
};
struct Bar : Foo
{
   char b;
};

sizeof(Foo)1sizeof(Bar)2

您使用:

创建Bar对象的数组
Bar* barPtr = new Bar[2];

barPtr指向的内存布局看起来像:

Bar(0)  Bar(1)
|       |
v       v
+---+---+---+---+
| a | b | a | b |
+---+---+---+---+

如果将指针传递给函数 Foo*,则该函数将把内存解释为(自sizeof(Foo) == 1):

Foo(0)  
|   Foo(1)
|   |
v   v
+---+---+
| a | a |
+---+---+

如您所见,Foo(1)实际上不是Foo对象。它实际上是Bar(0)Bar子对象。这很容易导致不确定的行为。根据基类和派生类具有的数据类型,它很容易崩溃您的程序。

关键点是指向派生类对象数组的指针不能被视为指向基类对象数组的指针。

R Sahu的很好解释。它清楚地描述了您的代码为什么不起作用并值得接受。

那你能做什么?

据我了解,您想将所有CTREE01传递到一个呼叫中的功能,并使该功能迭代所有CTREE01。

我知道的唯一方法是使容器(即数组,向量)持有基类指针,而不是Ctree01。

类似的东西:

class A
{
public:
    A() { cout << "A constructor" << endl;}
    virtual ~A() { cout << "A destructor" << endl;}
    void hello() { cout << "Hello from A" << endl;}
};
class B : public A
{
public:
    B() { cout << "B constructor" << endl;}
    ~B() override { cout << "B destructor" << endl;}
};
void f(array<A*,2>& t)
{
    for(auto e : t)
    {
        e->hello();
    }
}
int main()
{
    array<A*,2> z;   // Base class pointer array
    z[0]=new B;      // but it can still hold pointers to B
    z[1]=new B;
    f(z);
    delete z[0];
    delete z[1];
    return 0;
}

或使用向量而不是数组

class A
{
public:
    A() { cout << "A constructor" << endl;}
    virtual ~A() { cout << "A destructor" << endl;}
    void hello() { cout << "Hello from A" << endl;}
};
class B : public A
{
public:
    B() { cout << "B constructor" << endl;}
    ~B() override { cout << "B destructor" << endl;}
};
void f(vector<A*>& t)
{
    for(auto e : t)
    {
        e->hello();
    }
}
int main()
{
    vector<A*> z;
    z.push_back(new B);
    z.push_back(new B);
    f(z);
    delete z[0];
    delete z[1];
    return 0;
}