提问人:francesco 提问时间:11/17/2023 更新时间:11/17/2023 访问量:78
CRTP:将基类的访问限制为派生类的某些成员
CRTP: restrict access of Base class to some members of Derived class
问:
考虑 CRTP 模式。我想:template <class DerivedType> class Base
无法实例化基类
派生类中的(某些)方法只能通过基类的“接口”调用
基类只能访问 Derived 的某些私有成员
要满足 1.,声明 Base 类的构造函数就足够了。为了满足 2.,可以将方法设为私有,并声明 Base 类。但是,这将允许 Base 访问 Derived 的所有成员。protected
friend
例如,请参阅以下代码:
#include <iostream>
template <class T>
class Base {
protected:
Base() = default;
public:
void interface() const { static_cast<const T*>(this)->do_something(); }
// This should not compile
void interface_to_private() const { static_cast<const T*>(this)->do_something_private(); }
};
class Derived : public Base<Derived> {
friend class Base<Derived>;
void do_something() const { do_something_private(); }
// These should be not available to Base<Derived>
int i = 1;
void do_something_private() const { std::cout << "hello " << i << std::endl; }
};
int main()
{
Derived d;
d.interface();
d.interface_to_private(); // This should give error
return 0;
}
在示例代码中,我希望能够访问 ,但不能访问 ,也不能访问 成员字段。Base<Derived>
do_something()
do_something_private()
int i
我知道访问的粒度是一个已知的问题,例如,可以通过律师-客户习语来解决。但是,我无法弄清楚它是否真的可以与 CRTP 成语相结合。不言而喻,我不想要虚拟成员(这是使用 CRTP 的全部意义所在)。friend
我通过将方法隐藏在另一个类中找到了解决方案:
#include <iostream>
template <class T>
class Base {
protected:
Base() = default;
public:
void interface() const { static_cast<const T*>(this)->do_something(); }
// This should not compile
void interface_to_private() const { static_cast<const T*>(this)->do_something_private(); }
};
class Implementation {
int i = 1;
void do_something_private() const { std::cout << "hello " << i << std::endl; }
protected:
Implementation() = default;
public:
void do_something() const { do_something_private(); }
};
class Derived : public Base<Derived>, private Implementation {
friend class Base<Derived>;
};
int main()
{
Derived d;
d.interface();
// uncommenting gives compile error
// d.interface_to_private();
return 0;
}
取消注释该行会导致编译错误。d.interface_to_private();
虽然这似乎有效,但它似乎涉及,我想知道这是否是一个很好的解决方案,因为多重继承通常不受欢迎。
在这种情况下,有没有更好的解决方案,或者一个已知的“成语”?
答: 暂无答案
评论