在Modern C++ Design: Generic Programming and Design Patterns Applied
Andrei Alexandrescu中,主张保护政策的破坏者的主张是:
由于析构函数受到保护,因此只有派生类才能销毁策略对象,因此外部人员无法将delete应用于策略类的指针。但是,析构函数不是虚拟的,因此没有大小或速度开销
但是后来,他写了以下有关策略兼容性的段落:
如您所见,在实现策略之间的转换时,您具有双向灵活性。您可以在左侧实现转换构造函数,也可以在右侧实现转换运算符。
假设我们有2条政策:
class First{
public:
First() = default;
First(const First&) = default;
protected:
~First() = default;
};
class Second{
public:
explicit operator First() const {
return //what???
}
Second() = default;
Second(const Second&) = default;
Second(const First& ) {};
protected:
~Second() = default;
};
如何在不构造类型为First的临时对象的情况下创建从策略第二到策略第一的转换运算符?
问题在于,除了派生类之外,您无法创建具有受保护析构函数的对象。因此,禁止创建此类临时工的转换操作员。解决该问题的一种方法是通过构造函数进行建立First
和Second
接受explicit
:
#include <iostream>
class First;
class Second;
class First
{
public:
First() = default;
First(const First&) = default;
explicit First(const Second&);
int value() const { return x; }
protected:
~First() = default;
private:
int x = 1;
};
class Second
{
public:
Second() = default;
Second(const Second&) = default;
explicit Second(const First&);
int value() const { return x; }
protected:
~Second() = default;
private:
int x = 2;
};
First::First(const Second& s): x(s.value()) {}
Second::Second(const First& f): x(f.value()) {}
然后,您可以创建一个Host<Policy>
具有模板化转换构造函数的主机类模板,该转换构造函数可以转换策略Policy
和任意U
template<class Policy>
class Host
:
public Policy
{
public:
Host() = default;
template<class U>
Host(Host<U> const& other)
:
Policy(other)
{}
};
int main()
{
Host<First> h1;
Host<Second> h2;
Host<Second> h3(h1);
Host<First> h4(h2);
std::cout << h1.value() << "\n";
std::cout << h2.value() << "\n";
std::cout << h3.value() << "\n";
std::cout << h4.value() << "\n";
}
现场例子。
请注意,确实建议使用受保护的析构函数和公共继承,但特别建议您安全使用“丰富的”(即有状态)策略。对于无状态策略,还可以使用受保护的继承和公共析构函数。对于这些策略,转换运算符可以生成临时文件。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句