为了提高创建和销毁对象时的性能,池是一种可能。
在某些情况下,我不想进入低级别的技术,如自定义分配程序或char[]。
另一种方法是创建对象池。
然而,这种技术并不适用于类内字段(内联)初始化。
一开始,我根本不认为这是个问题。
然而,这种模式不断地重复出现上百次,我认为我应该有一些对策。
示例
假设我的程序的第一个版本如下所示:
class Particle{
int lifeTime=100; //<-- inline initialization
//.... some function that modify "lifeTIme"
};
int main(){
auto p1=new Particle();
delete p1;
//... many particle created & deleted randomly ...
};在采用对象池之后,我的程序可以是:-
class Particle{
int lifeTime=100; //<---- maintainability issue
void reset(){
lifeTime=100; //<---- maintainability issue
}
};
int main(){
auto* p1=pool.create();
//.... "Particle::reset()" have to be called somewhere.
};重复的代码会引起一些可维护性问题。
问题
如何在不牺牲代码可维护性和可读性的情况下,对具有内联字段初始化的现有对象采用对象池?
我现在的解决办法
我通常让构造函数调用reset()。
class Particle{
int lifeTime;
public: Particle(){
reset(); //<---- call it here, or "pool" call it
}
void reset(){
lifeTime=100;
}
};的缺点:与旧的内联初始化相比,降低了代码的可读性:-
int lifeTime=100; 对不起,如果这个问题太初学了,我是C++新手。
发布于 2017-04-22 03:43:19
这是std::unique_ptr<>常用的一种用法
class Base {
static constexpr int lifespan = 100;
int lifetime = lifespan;
public:
void reset() noexcept { lifetime = lifespan; }
}
struct Deleter {
void operator ()(Base* const b) const {
b->reset();
}
};
struct Particle : Base {
// ...
};
struct Pool {
std::unique_ptr<Particle, Deleter> create() {
// ...
}
}
int main() {
// ...
auto p1 = pool.create();
}发布于 2017-04-22 03:55:17
这一问题的解决方案实际上取决于
lifeTime of 100lifeTimelifeTime重置为100。你已经部分地回答了第一个问题,尽管我敢打赌你所说的提高性能的目标不是基于“你认为你需要提高性能”。实际上,这样一个目标应该建立在衡量业绩不够充分的基础上,否则,这只不过是过早的优化。
无论如何,如果我为了讨论而假设上述所有问题都有很好的答案,我会做以下几件事;
class Particle
{
public:
// member functions that provide functions used by `main()`.
private: // note all the members below are private
Particle();
void reset()
{
lifeTime=100;
};
friend class Pool;
};
class Pool
{
public:
Particle *create()
{
Particle *p;
// obtain an object for p to point at
// that may mean release it from some "pool" or creating a new one
p->reset();
return p;
};
void give_back(Particle *&p)
{
// move the value of p back into whatever the "pool" is
p = NULL; // so the caller has some indication it should not use the object
};
};
int main()
{
// presumably pool is created somehow and visible here
auto* p1=pool.create();
// do things with p1
pool.give_back(p1); // we're done with p1
auto *p2 = pool.create();
// p2 might or might not point at what was previously p1
}注意,值100只出现在reset()函数中。
将构造函数设置为私有函数和Pool为friend的原因是为了防止意外创建新对象(即强制使用池)。
或者,让Particle::reset()成为public允许main()调用p1->reset(),但这不是必需的。但是,从池中获得的所有对象(无论是新建对象还是重用对象)都将被重置。
我可能还会使用std::unique_ptr<Particle>,以便正确管理对象的生存期,例如,如果您忘记将对象返回到池中。我将把实现这类事情作为一项练习。
https://stackoverflow.com/questions/43554804
复制相似问题