判断类的继承性

比如类定义如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <memory>
#include <iostream>
 
using namespace std;
 
class BaseA
{
public:
	int i_;
};
 
class ChildA //: public BaseA
{
public:
	int i_;
};

如下的方法只会报编译错误

1
2
3
4
5
6
7
8
9
    ChildA *a = (ChildA *)1;
    if (NULL == static_cast<BaseA*>(a))
    {
        cout << "ChildA does not inherit from BaseA 2." << endl;
    }
    else
    {
        cout << "ChildA inherits from BaseA 2." << endl;
    }

如下的方法才能编译中自动检查类的继承性并作相应处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template<class T, class = void>
struct IsFromBaseA : false_type {};
 
template<class T>
struct IsFromBaseA<T, void>
    : is_convertible<T*, BaseA*>::type {};
 
int main()
{
    if constexpr (conjunction_v<IsFromBaseA<ChildA>>)
    {
        cout << "ChildA inherits from BaseA." << endl;
    }
    else
    {
        cout << "ChildA does not inherit from BaseA." << endl;
    }
    return 1;
}

这是enable_shared_from_this实现的基础。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <memory>
 
using namespace std;
 
class Aa : public enable_shared_from_this<Aa> // 'public' is necessary.
{
public:
	shared_ptr<Aa> retThis()
	{
		return shared_from_this();
	}
};
 
int main()
{
	shared_ptr<Aa> p1 = make_shared<Aa>();
	shared_ptr<Aa> p2 = p1->retThis();
 
	p2.reset();
	p1.reset();
	return 0;
}

当p1在构造时,会检查Aa是否是enable_shared_from_this派生的类,如果是,则在enable_shared_from_this类中维护一个引用计数;如果不是enable_shared_from_this派生的,则在shared_ptr类中维护一个引用计数。