C++ 设计NVI(Non-Virtual Interface)
【摘要】
目录
RAII(Resource Acquisition Is Initialization)
ScopeGuard
NVI(Non-Virtual Interface)
CRTP(Curiously Recurring Template Pattern)
PIMPL(Private Implementation)
...
目录
RAII(Resource Acquisition Is Initialization)
CRTP(Curiously Recurring Template Pattern)
RAII(Resource Acquisition Is Initialization)
即资源获取就是初始化,是一种管理资源的机制。
如管理new操作符的资源:
-
class A
-
{
-
public:
-
int *p;
-
-
A(int n)
-
{
-
p = new int[n];
-
}
-
~A()
-
{
-
delete p;
-
}
-
};
-
-
int main()
-
{
-
A a(10);
-
// a.p
-
return 0;
-
}
只写了一个简单的示例。
一个经典的案例:lock_guard类,源代码如下
-
// CLASS TEMPLATE lock_guard
-
template<class _Mutex>
-
class lock_guard
-
{ // class with destructor that unlocks a mutex
-
public:
-
using mutex_type = _Mutex;
-
-
explicit lock_guard(_Mutex& _Mtx)
-
: _MyMutex(_Mtx)
-
{ // construct and lock
-
_MyMutex.lock();
-
}
-
-
lock_guard(_Mutex& _Mtx, adopt_lock_t)
-
: _MyMutex(_Mtx)
-
{ // construct but don't lock
-
}
-
-
~lock_guard() noexcept
-
{ // unlock
-
_MyMutex.unlock();
-
}
-
-
lock_guard(const lock_guard&) = delete;
-
lock_guard& operator=(const lock_guard&) = delete;
-
private:
-
_Mutex& _MyMutex;
-
};
实例化的时候加锁,生命周期结束的时候自动解锁。
ScopeGuard
这个方法是定义一个ScopeGuard模板类,用于管理临时使用的资源。
把临时资源的释放操作写成lambda表达式,申请ScopeGuard实例存放这个表达式,实例生命周期结束时自动
代码:
-
template <typename Lambda>
-
class ScopeGuard
-
{
-
public:
-
ScopeGuard(Lambda &&lam): lambda (lam) {
-
}
-
~ScopeGuard() {
-
lambda();
-
}
-
private:
-
Lambda lambda;
-
};
-
-
template <typename T>
-
ScopeGuard<T> GetScopeGuard(T &&lambda)
-
{
-
return ScopeGuard<T>(move(lambda));
-
}
-
-
int main()
-
{
-
int* p = new int[100];
-
GetScopeGuard([&] {delete[] p; });
-
return 0;
-
}
NVI(Non-Virtual Interface)
NVI是用非虚函数调用虚函数,把非虚函数作为接口。
-
class A
-
{
-
public:
-
void show()
-
{
-
cout << "A\n";
-
print();
-
}
-
virtual void print() {};
-
};
-
class B :public A
-
{
-
public:
-
void print()
-
{
-
cout << "x=" << x;
-
}
-
private:
-
int x;
-
};
-
-
int main()
-
{
-
B b;
-
b.show();
-
return 0;
-
}
CRTP(Curiously Recurring Template Pattern)
奇异的递归模板模式,指的是子类继承一个模板类,模板的特化类型是子类本身。
最简代码:
-
#include<iostream>
-
using namespace std;
-
-
template<typename T>
-
class Base
-
{
-
public:
-
void virtualFunc()
-
{
-
static_cast<T*>(this)->realFunc();
-
}
-
};
-
-
class Chird :public Base<Chird>
-
{
-
public:
-
void realFunc()
-
{
-
cout << "real func";
-
}
-
};
-
-
int main()
-
{
-
Chird().virtualFunc();
-
return 0;
-
}
这个简单的例子就能看出CRTP的写法,也能看出,其实本质上静态多态。
CRTP的好处是,静态多态比继承虚函数的动态多态要快。
应用:
PIMPL(Private Implementation)
通过一个私有的成员指针,将指针所指向的类的内部实现全部隐藏。
普通代码:
-
class A
-
{
-
public:
-
int f(int n)
-
{
-
return f1(n) + n + f2(n);
-
}
-
private:
-
int f1(int n)
-
{
-
return n * n * n;
-
}
-
int f2(int n)
-
{
-
return n > 0 ? 1 : -1;
-
}
-
};
PIMPL代码:
-
class B;
-
class A
-
{
-
public:
-
A()
-
{
-
opt = new B();
-
}
-
int f(int n)
-
{
-
return opt->f1(n) + n + opt->f2(n);
-
}
-
private:
-
B* opt;
-
};
-
-
class B
-
{
-
public:
-
int f1(int n)
-
{
-
return n * n * n;
-
}
-
int f2(int n)
-
{
-
return n > 0 ? 1 : -1;
-
}
-
};
文章来源: blog.csdn.net,作者:csuzhucong,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/nameofcsdn/article/details/125222648
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)