类内非静态字段初始化 + 对象池 - >降低可维护性/可读性
in-class in-line non-static field initialization + object pool -> decrease maintainability/readability
创建&破坏物体,合并是可能的。
在某些情况下,我不想使用自定义分配器或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 的新手。
这是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();
}
解决方案的解决方案实际上取决于
的组合- 为什么需要池对象?
- 为什么对象需要具有
100
的默认lifeTime
? - 为什么对象需要更改其
lifeTime
? - 为什么从池中获得的现有对象需要将其
lifeTime
重置为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
A friend
是为了防止意外创建新对象(即强制使用池(。
可选,使Particle::reset()
为public
允许main()
调用p1->reset()
,但这不是必需的。但是,从池中获得的所有对象(无论创建新鲜还是重复使用(都将被重置。
我可能还会使用std::unique_ptr<Particle>
,因此,如果您忘记将对象还给池中,则可以正确管理对象的寿命。我将把这种事情作为练习留下。
- EASTL矢量<向量<int>>连续的
- 是否值得降低我的代码的可读性,以便在出现内存不足错误时提供异常安全性?
- 命名空间信息会影响C++的可读性
- C++中的异常是否仅用于提高可读性?
- 发布代码的 gdb 堆栈跟踪可读性如何影响 x64?
- clang-tidy 忽略 Windows 上的可读性标识符命名
- 运行时与编译时多态性:更好的可读性与编译时错误检查,更重要的是
- 有没有办法在带有空格C++源代码中写入大量数字以使其更具可读性?
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- C 字符串比较“祝您好运”&gt;“再见”
- 将 SFINAE 条件移到最左侧以提高可读性
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C 17类模板参数类型扣除 - 可读性
- 类内非静态字段初始化 + 对象池 - >降低可维护性/可读性
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- C 操作员&gt;&gt;与突变器过载
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 是否需要使用 - &gt;运算符在C 中调用成员函数时
- 什么是模板&lt;&gt;inline bla bla
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型