在类的第一个/最后一个实例存在之前/之后调用一对函数.有没有更好的方法?
Call a pair of functions before/after the first/last instance of a class exists. Is there a better way?
我有一对函数init
和shutdown
以及一些类RefTest
。
我需要在首次实例化RefTest
时调用init
,并在销毁RefTest
的最后一个实例时调用shutdown
。这也可能在一个程序中多次发生。
我想出的一个实现如下所示。但这对我来说似乎并不理想(例如,它不是线程安全的(。 我想过使用std::shared_ptr
并将这些功能放在类 ctor/dtor 中,但我似乎无法让它工作。
有没有更好的方法可以做到这一点?
测试实现:
#include <iostream>
void init() { std::cout << "init() called" << std::endl; }
void shutdown() { std::cout << "shutdown() called" << std::endl; }
static size_t s_refCount = 0;
class RefTest
{
public:
explicit RefTest()
{
if(s_refCount++ == 0) init();
std::cout << "ctor()" << std::endl;
}
~RefTest()
{
std::cout << "dtor()" << std::endl;
if(--s_refCount == 0) shutdown();
}
};
int main(int argc, char *argv[])
{
{
RefTest t1;
RefTest t2;
RefTest t3;
}
RefTest t4;
return 0;
}
输出:
init() called
ctor()
ctor()
ctor()
dtor()
dtor()
dtor()
shutdown() called
init() called
ctor()
dtor()
shutdown() called
但这
对我来说似乎并不理想(例如,它不是线程安全的(。
std::atomic<int>
帮助解决这个问题 - 但只是问题的一部分。它可以使计数器线程安全,这样您就不会尝试调用init
/shutdown
太多次。
它不会解决在第一次调用仍在执行时第二次调用构造函数的问题。(然后使用部分构造的对象(
有没有更好的方法可以做到这一点?
普遍接受的最佳做法是为每个类分配一个作业。
例:
#include <iostream>
#include <atomic>
// one class, one job
struct initialiser
{
initialiser()
{
if (0 == s_refCount++) init();
}
initialiser(initialiser const&)
{
++s_refCount;
}
initialiser& operator=(initialiser const&)
{
++s_refCount;
return *this;
}
~initialiser()
{
if(--s_refCount == 0) shutdown();
}
private:
void init() { std::cout << "init() called" << std::endl; }
void shutdown() { std::cout << "shutdown() called" << std::endl; }
static std::atomic<size_t> s_refCount;
};
std::atomic<size_t> initialiser::s_refCount { 0 };
// one class, one job. Allow encapsulation to do the reference counting
class RefTest
{
public:
explicit RefTest()
{
std::cout << "ctor()" << std::endl;
}
// rule of 5
RefTest(RefTest const &) = default;
RefTest(RefTest &&) = default;
RefTest& operator=(RefTest const &) = default;
RefTest& operator=(RefTest &&) = default;
~RefTest()
{
std::cout << "dtor()" << std::endl;
}
private:
initialiser init_;
};
int main(int argc, char *argv[])
{
{
RefTest t1;
RefTest t2;
RefTest t3;
}
RefTest t4;
return 0;
}
预期产出:
init() called
ctor()
ctor()
ctor()
dtor()
dtor()
dtor()
shutdown() called
init() called
ctor()
dtor()
shutdown() called
另请注意不违反 3/5 规则
相关文章:
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 有没有办法使用递归函数找到数组中最小值的 INDEX?C++
- 有没有办法按值将纯抽象类的所有子类传递给 C++ 中的函数?
- 有没有一个 c++ gmp 库函数与 python gmpy2 库 divm(..) 函数相同?
- 有没有办法捕获 STL 函数未被赋予正确参数的异常?
- C++ STD 函数运算符:有没有一种方法可以通过函数将一个向量映射到另一个向量上?
- 有没有办法将重载的类函数绑定到函数对象?
- 有没有办法在不使用 #ifdef 的情况下不编译发布版本中的单元测试函数体?
- 有没有办法将指定不同类的 std::make_unique 传递到函数中
- C++如果采用类类型的函数被传递派生类型,有没有办法给出错误?
- 有没有办法保证析构函数的相对顺序?
- 有没有办法使用该类的构造函数初始化另一个类的私有部分内的对象数组?
- 有没有办法在另一个函数中加入线程?(即超出其自身范围)
- 有没有办法计算函数内arry的长度而不是作为参数传入?
- 在类的第一个/最后一个实例存在之前/之后调用一对函数.有没有更好的方法?
- 函数有没有办法自动检测其参数的数据类型?(请不要建议函数重载)
- 在对象上调用静态成员函数——有没有办法将其转化为编译器错误