抽象类中可以有静态数据成员吗?
我设计了一系列相关的类,为了能够管理它们,我让它们从一个抽象类派生。
这些类都需要访问一系列共享资源,我发现自己在每个类中创建了一个指针向量,它们全部相同(它们必然必须相同)。似乎在基类中创建一个静态成员将使所有派生类都可以访问该向量,这意味着我只需要构建它一次(构建后它也不会改变,只需查找)。
我的问题是这是否可以,如果可以,我如何构建它,而不从派生类之一调用“填充向量”方法?
我的想法是做类似的事情
class Resource {};
enumR {RES0, RES1};
class AbstractClass
{
public:
virtual void OnInit() = 0;
void static fillVector(Resource* pResource, enumR Resourcename)
{lResource[Resourcename]=pResource;};
protected:
static vector<Resource*> lResource;
};
vector<Resource*> AbstractClass::lResource;
int main()
{
Resource res0, res1;
AbstractClass::fillVector(&res0, RES0);
AbstractClass::fillVector(&res1, RES1);
return 0;
};
然后当我实例化从 AbstractClass 派生的任何类的对象时,我可以访问 lResource 向量,这就是我想要的。
这行得通吗?可怕吗?可以吗?
I designed a series of related classes, and in order to be able to manage them I made them derive from a single abstract class.
These classes all need access to a series of shared resources, and I found myself creating a vector of pointers in each, all of them identical (they necessarily must be). It seems like making a static member in the base class would give all of the derived classes access to this vector, meaning I need only build it once (it's not going to change either after it's been built, just looked up).
My question is if this is ok, and if so, how can I then build it, without calling a 'fill the vector' method from one of the derived classes?
My thinking was to do something like
class Resource {};
enumR {RES0, RES1};
class AbstractClass
{
public:
virtual void OnInit() = 0;
void static fillVector(Resource* pResource, enumR Resourcename)
{lResource[Resourcename]=pResource;};
protected:
static vector<Resource*> lResource;
};
vector<Resource*> AbstractClass::lResource;
int main()
{
Resource res0, res1;
AbstractClass::fillVector(&res0, RES0);
AbstractClass::fillVector(&res1, RES1);
return 0;
};
Then when I instantiate an object of any class derived from AbstractClass, I'd have access to the lResource vector, which is what I want.
Would this work? Is it horrible? Is it ok?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
它会起作用,其中工作=编译&跑步。
但是,所有子类都将访问相同的静态向量,这意味着每个子类不会有不同的静态向量副本。
为了更好地解释我的意思,请阅读以下主题:
静态字段是否继承?
解决方案:
一种解决方案是为您的父类提供一个模板类,如下所示:
在上面的代码中,您将获得 ChildA 的所有实例的共享资源,以及在实例<之间共享的另一个资源。 /em> 的儿童 B.
是吗?
嗯,我认为这不算好。与此相关的讨论之一是对以下 SO 问题的评论以及我对该问题的回答:
如何执行“静态重载” C# 中的 const?
It would work, where work = compile & run.
However, all child classes will be accessing the same static vector, which means there won't be a different copy of the static vector for each child class.
For a better explanation of what I mean read the following So thread:
Are static fields inherited?
SOLUTION:
One solution is to have your parent class a template class as follows:
In the above code, you will get a shared resource for all instances of ChildA and another one shared between instances of ChildB.
Is it right?
Well, I think it is not considered good. One of the related discussions to this is in comments to the following SO question and also under my answer to the question:
How to do "static overloaded const" in C#?
更好的解决方案是只创建一个带有向量的对象,然后仅实例化它一次,并为其他类提供指向它的指针或引用。除非必要,否则绝对应该避免使用静态数据,而这并不是必要的。
The better solution would be to just make an object with the vectors in and then only instantiate it once and give the other classes a pointer or reference to it. Static data should be absolutely avoided unless necessary and this just isn't necessary.
您可以添加静态函数来初始化静态向量:
You can add a static function to initialise your static vector:
您可以尝试 boost::assign::list_of ,如下所示:
You could try boost::assign::list_of, something like this:
我在这里有几点。
I have few points here.
由于您正在创建“资源指针”向量并且没有提前为对象保留空间,因此您的系统将来可能会崩溃。为什么?
当您插入元素时,Vector 会创建一个内存块,并使用同一块,直到达到其容量为止。一旦达到其容量并且插入一个新元素,向量将分配一个新内存(是先前分配的内存的两倍)并将所有现有元素复制到新内存中。由于这是一个“指针”向量,因此它将使所有引用无效。
Since you are creataing the vector of "resource pointer" and not reserving the spaces for object in advance ,your sysetem might crash in future. Why?
Vector create a block of memory when you insert element and uses the same block until it hits its capcity. Once it hits its capcality and you inset a new element, vector will allocate a new memory (twice as previous allocated memory) and copies all the existing elements into new memory. Since this is a vector of "pointers", it is going to invaliadate all the refernces.
在这些情况下,我通常做的是添加一个中间模板化层,这样我就有了这样的结构:
定义抽象接口:
将子级常用的资源放入模板中,并在必要时使用 CRTP 定义样板函数,保留必要的接口函数仍然是抽象的
最后,不同的具体类完成实现,并在必要时对这些资源做一些特殊的事情
What I usually do in these cases is add a middle templated layer so I have a structure like this:
Define your abstract interface:
Put the resources commonly used by the child in a template and define the boiler-plate function using CRTP if necessary keeping the necessary interface function still abstract
Finally the different concrete classes complete the implementation and do something special with those resources if necessary