派生对象的数组 [英] Arrays of derived objects

查看:53
本文介绍了派生对象的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




是否有针对以下问题的通用解决方案:


我有一组B类实例。 B是公开派生自

类A.然后我有一个名为Buffer的类,它通常负责分配和释放数组。
分配和释放数组。类缓冲区只知道其内部数组中包含的对象

是从A类派生的,而不是它们是b / b
,因此Buffer的成员变量是类型A *,

指向该数组的开头。我知道索引元素

将不适用于这种机制,所以我宁愿再增加一个间接的
级别,也就是A类型的元素数组*指向每个B

对象。但是我认为(请纠正我,如果我错了)需要

分别分配每个对象B会降低操作速度,所以我希望

来使用新的[ ]一次而不是新的多次。好的,我可以使用第一个新的

B [...]然后在数组中设置一个A *元素指向

B的每个实例。但是那样明智?还有另外一种方法吗?如果指定给它的指针类型与数组中包含的元素的

类型完全匹配,那么delete []会正确清理

内存吗? (我的意思是,如果在缓冲区的析构函数中删除了

对象B的数组,只知道

元素是从A类派生的)


我不想在类Buffer中使用虚函数,因为它们会导致速度上限为b
。我也不想将其模板化,因为它应该足以让它知道其内部数组中包含的对象

来自A类。但它仍然能够索引元素

并正确销毁它们。最好的办法是什么?


非常感谢你提前的帮助,


杰克

Hi,

Is there a general solution for the following problem:

I have an array of instances of class B. Class B is publicly derived from
class A. Then I have a class named Buffer that generally takes care of
allocating and deallocating arrays. Class Buffer knows only that the objects
contained in its internal array are derived from class A but not that they
are exactly of type B, so Buffer has a member variable of type A* that
points at the beginning of that array. I know that indexing the elements
will not work with this mechanism, so I should rather have one more level of
indirection, that is, an array of elements of type A* that point to each B
object. But I think (please correct me if I am wrong) that the need to
allocate each object B separately slows down the operation, so I would like
to use new[] once instead of new multiple times. Okay, I can use first new
B[...] and then set one A* element in the array to point at each instance of
B. But is that sensible? Is there another way? Will delete[] clean up the
memory correctly if the pointer type given to it does not exactly match the
type of the elements contained in the array? (I mean, if the array of
objects B is deleted in the destructor of Buffer that knows only that the
elements are derived from class A)

I don''t want to use virtual functions in class Buffer, because they cause
overhead in speed. I don''t want to templatize it either, because it should
be enough for it to know that the objects contained in its internal array
are derived from class A. But still it should be able to index the elements
and destroy them correctly. What is the best way to do it?

Thank you very much for your help in advance,

Jack

推荐答案

嗨再次,


我决定用一段代码来澄清我的问题:


A类{...};

B类:公共A {...};

模板< typename T>

class Buffer

{

public:

Buffer(T * p,size_t i):m_p(p),m_i( i){}

~Cluffer(){delete [] m_p;} //这可以吗?

T& operator [](int i){/ *如何实现这个? * /}

私人:

T * m_p;

size_t m_i;

};


int main()

{

缓冲区b< A>(新B [5],5);

返回0;

}


与我之前所说的相反,Buffer可以(也可能应该)采取

基类作为模板参数(在本例中为A类),但我的意思是

我想留下它以便它不会将派生类作为

a模板参数(在本例中为B类)。


Jack
Hi again,

I decided to try to clarify my questions by a piece of code:

class A { ... };
class B : public A { ... };
template<typename T>
class Buffer
{
public:
Buffer(T* p, size_t i) : m_p(p), m_i(i) {}
~Buffer() {delete[] m_p;} // Is this okay?
T& operator[](int i) { /* How to implement this? */ }
private:
T* m_p;
size_t m_i;
};

int main()
{
Buffer b<A>(new B[5], 5);
return 0;
}

In contrast to what I said earlier, Buffer can (and probably should) take
the base class as a template parameter (in this case class A), but I meant
that I would like to leave it so that it does not take the derived class as
a template parameter (in this case class B).

Jack


Jack写道:
嗨再次,

我决定用一段代码来澄清我的问题:


优秀。

A类{ ......};


这不编译。这些点实际上并不是必需的,因此编译它会更好。这真的是你真的想要点:

A级{/ * ... * /};

B级:公共A {...};


再次。

模板< typename T>
类缓冲区
{
公开:
缓冲区(T * p,size_t i):m_p(p),m_i(i){}
~Buffer(){delete [] m_p;} //这可以吗?


如果参数p指向一个用new []分配的数组,并且它没有

已被删除[],是的。否则你可能有未定义的

行为。


为什么你不保证它,并在构造函数中进行分配?

T& operator [](int i){/ *如何实现这个? * /}
私人:
T * m_p;
size_t m_i;
};

int main()
{
缓冲液b< A>(新B [5],5);


好​​吧,我想我看到了上面的问题。多态性。

返回0;
}

与我之前所说的相反,Buffer可以(也可能应该)将基类作为基类一个模板参数(在本例中是A类),但我的意思是
我想保留它,以便它不会将派生类作为模板参数(在本例中为B类)。
Hi again,

I decided to try to clarify my questions by a piece of code:
Excellent.
class A { ... };
This doesn''t compile. The dots are really not necessary, it''s much
better to have it compile. Do this is you REALLY want the dots:
class A {/* ... */};
class B : public A { ... };
And again.
template<typename T>
class Buffer
{
public:
Buffer(T* p, size_t i) : m_p(p), m_i(i) {}
~Buffer() {delete[] m_p;} // Is this okay?
If the argument p points to an array allocated with new[], and it hasn''t
already been deleted[], yes. Otherwise you probably have undefined
behaviour.

Why don''t you guarantee it, and do the allocation in the constructor?
T& operator[](int i) { /* How to implement this? */ }
private:
T* m_p;
size_t m_i;
};

int main()
{
Buffer b<A>(new B[5], 5);
OK, I think I see the above problem. Polymorphism.
return 0;
}

In contrast to what I said earlier, Buffer can (and probably should) take
the base class as a template parameter (in this case class A), but I meant
that I would like to leave it so that it does not take the derived class as
a template parameter (in this case class B).




我可能会这样:


#include< vector>


class A {};

class B:public A {};


template< class Base,class Derived>

class Buffer {

public:

Buffer(size_t size):buffer_(size){}

Base& operator [](size_t i){return buffer [i]; }

private:

std :: vector< Derived> buffer_;

};


int main(){

缓冲区< A,B> buf(5);

}


无论如何,在构造时,你都在使用派生类型。

我没有看到这一点,因为在operator []中,你正在返回一个

引用,无论如何,这将能够以多态方式使用。 />

无论如何,无论你决定做什么,你都需要确保你不能构建一个不正确的缓冲区,在你的代码上调用以下内容将

是个问题:


缓冲区b< A>(新B [5],6)


它是'根本没必要引入那个问题,所以我已经改变了构造函数的
(和简化)。


另外,你会注意到我'已经捕获了一个

std :: vector中的实际内容,因为我不理解指针和数组。


Ben Pope

-

我不仅仅是一个数字。对很多人来说,我被称为字符串...



I would probably make it like this:

#include <vector>

class A {};
class B : public A {};

template<class Base, class Derived>
class Buffer {
public:
Buffer(size_t size) : buffer_(size) {}
Base& operator[](size_t i) { return buffer[i]; }
private:
std::vector<Derived> buffer_;
};

int main() {
Buffer<A, B> buf(5);
}

At the point of construction, you''re using the derived type, anyway.

I don''t see the point, since in operator[], you''re returning a
reference, and that will be able to be used polymorphically, anyway.

Anyway, whatever you decide to do, you need to make sure that you cannot
construct an incorrect buffer, calling the following on your code would
be a problem:

Buffer b<A>(new B[5], 6)

It''s simply not necessary to introduce that problem, so I''ve changed
(and simplified) the constructor.

Also, you''ll notice I''ve captured the actual containing within a
std::vector, since I don''t understand pointers and arrays.

Ben Pope
--
I''m not just a number. To many, I''m known as a string...


Ben,


感谢您的回复。我想你不明白我的问题的动机

,所以请让我解释一下:


我说类Buffer不应该知道派生的类型

类(换句话说,解决方案不是将派生类作为

模板参数。出于同样的原因,std :: vector不能用过的)。

的原因是Buffer是在静态库中实现的,

还包含必须能够使用Buffer类的其他组件。所以

如果Buffer的实现取决于派生类的类型

(只有库的客户端代码知道)它不能被
那些其他库组件。


而且,关于delete []的问题是关于它是否正常工作

如果指针类型正确赋予它并不是要删除的数组中包含的元素类型

的完全匹配。


问候,


杰克
Ben,

Thank you for your reply. I think that you did not understand the motivation
of my questions, so please let me explain:

I said that class Buffer should not be aware of the type of the derived
class (in other words, a solution is not to put the derived class as a
template parameter. For the same reason std::vector cannot be used). The
reason for this is that Buffer is implemented in a static library, which
also contains other components that must be able to use the Buffer class. So
if the implementation of Buffer depends on the type of the derived class
(which is only known to the client code of the library) it cannot be used by
those other library components.

And also, my question regarding delete[] was about whether it works
correctly if the pointer type given to it is not an exact match of the type
of the elements contained in the array to be deleted.

Regards,

Jack


这篇关于派生对象的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆