C++传递函数指针数组
我在向函数传递指针数组时遇到问题 CTree01类是CDECoOptionObj的子类。 当我使用for循环时,它工作得很好 这是我的密码:C++传递函数指针数组,c++,pointers,C++,Pointers,我在向函数传递指针数组时遇到问题 CTree01类是CDECoOptionObj的子类。 当我使用for循环时,它工作得很好 这是我的密码: CTree01 *trees01; int numTree01 = ...; trees01 = new CTree01[numTree01]; //main loop for(int i=0;i<numTree01;i++) { { //Everything is working okay her
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();
}
}
它可以工作,只有当我渲染索引大于0的对象时才会崩溃,所以我认为传递给函数的参数一定有问题。让我看看是否可以用几个简单的类来解释这个问题 假设你有:
struct Foo
{
char a;
};
struct Bar : Foo
{
char b;
};
sizeofFoo为1,SizeOffbar为2
并使用以下方法创建条形图对象数组:
Bar* barPtr = new Bar[2];
barPtr指向的内存布局如下所示:
Bar(0) Bar(1)
| |
v v
+---+---+---+---+
| a | b | a | b |
+---+---+---+---+
如果将该指针传递给函数a Foo*,该函数将解释内存,因为sizeofFoo==1:
正如您所看到的,Foo1并不是一个真正的Foo对象。它实际上是Bar0的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;
}
您使用类型CDecorationObj处理objs[]-数组,它的长度肯定与CTree01不同,比如说,CDecorationObj的大小为10字节,CTree01的大小为20字节,当您访问objs[1]时,您只是进入下一个树对象内存的一半,在调用Drawonterain时,您得到了一个错误的地址。尝试使用指向内部元素的指针,例如CTree**和CDecorationObj**您不应该仅仅因为这样就进行更新和删除,尤其不应该将原始指针用作数组。Google std::vector。我用CDecorationObj**objs替换了CDecorationObj*objs,但现在出现了一个错误,无法将参数1从'D_CTree02**'转换为'CDecorationObj**'@Barcio77 Ok,但这还不够^^^^您还必须为每个CTree分配新的参数-我希望您也这样做了。考虑到我们的身体增强的糕点朋友的上述评论,你应该考虑使用STD::矢量。另见下面R Sahu的答案,他更详细地解释了我所说的。底线是,你需要给出一个指向元素的指针列表,可以是指向基的指针,也可以是指向基的指针向量。好的,我现在明白了,它正在工作!谢谢你写下这个解决方案
Foo(0)
| Foo(1)
| |
v v
+---+---+
| a | a |
+---+---+
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;
}