- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
无论我在哪里阅读有关 CRTP 的文章,实际上在我编写的代码中,CTRP 类层次结构都类似于以下内容:
template< class T >
class Base
{
public:
int foo_interface()
{
return static_cast< T* >(this)->foo_implementation();
}
};
class Derived : public Base< Derived >
{
friend class Base< Derived >;
int foo_implementation()
{
return 5;
}
};
也就是接口(interface)名称和实现方法不同。现在,我通常不希望实现方法从外部可见,这需要上面的 friend 声明,并且在多级层次结构中证明是一个主要的问题(即使使用描述的技巧 here )。
现在,我想到了以下内容:
// Base class
template< class T >
class A
{
public:
int foo()
{
std::cout << "I'm in A's foo!\n";
return static_cast< T * >(this)->foo();
}
};
// Deriving class
class B : public A< B >
{
public:
int foo()
{
std::cout << "I'm in B's foo!\n";
return 5;
}
};
// Deriving class with a nasty surprise...
class C: public A< C >
{
public:
// ...crap, no foo to be found!
int bar()
{
std::cout << "I'm in C's bar!\n";
return 12;
}
};
template< class T >
int call_foo(A< T > & t)
{
return t.foo();
}
B b;
C c;
现在,call_foo(b)
就像我期望的那样工作,调用 B 的 foo() 实现。同样,call_foo(c)
也按预期工作(因为它没有……由于显而易见的原因而陷入无限循环)。我看到的一个缺点是,如果我忘记在派生类中实现一个方法(或者拼写错误,忘记将其限定为 const,等等......),我会得到一个无限循环,所以它可能会产生那种错误有点难找,因为它们在编译时没有被捕获。但除此之外,它几乎和普通虚函数一样简单,而且我不必为隐藏实现方法而苦恼。它看起来简单而优雅,但似乎没有人在使用它……我的问题是,有什么问题?为什么不使用这种方法?隐藏实现方法只是没什么大不了的吗?或者当我在实际项目中尝试这种方法时,是否有某种不可估量的邪恶力量潜伏在那里准备吞噬我的灵魂?
最佳答案
除了您提到的同名接口(interface)函数及其实现的问题外,CRTP 背后没有潜伏的“邪恶力量”,但在我看来,这有点像“自找麻烦”。
至于“为什么不使用这种方法?”这个问题,我认为情况并非如此。这种方法在需要时被广泛使用;但没有一种设计模式始终 有意义。在某些特定的设计情况下,每一种都会派上用场,CRTP 也不异常(exception)。
当您有几个、不相关类支持公共(public)接口(interface)但略微实现它时,CRTP 最有用strong>(不完全)不同。如果我以粗体显示的这些词中任何没有描述您的设计用例,则 CRTP 可能毫无意义:
size()
方法,创建一个基类只是为了保存该方法可能是一个无用的细粒度分解; 但是,当您的设计情况满足上述四个属性的所有时,那么您肯定有 CRTP 的用例:没有虚函数开销,编译器可以完全优化您的代码,您可以清楚地分离接口(interface)和实现,通过捕获通用实现逻辑来实现最小冗余,等等。
但是,您可能会意识到这种情况并不常见。希望这能回答您的问题。
关于c++ - 为什么 CRTP 实现和接口(interface)方法的命名不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14625801/
编写一个仅用于集中其他接口(interface)的接口(interface)是好的做法还是坏的做法? interface InterfaceA : InterfaceB, InterfaceC { }
有没有一种方法可以确定具体类型从任意接口(interface)列表?我知道类型转换,但我想知道所有满意的接口(interface)。 例如,给定: type Mover interface { Mo
我正在尝试制作斐波那契堆。 (在我正在上的算法课中多次提到它们,我想检查一下。)我希望堆使用任何类型的节点,所以我定义了一个 Node 接口(interface): package node type
这是我的代码: type IA interface { FB() IB } type IB interface { Bar() string } type A struct {
示例 A: // pseudo code interface IFoo { void bar(); } class FooPlatformA : IFoo { void bar() {
合并它编译的 leppies 反馈 - 但 IMO 有一些缺点,我希望编译器强制每个子类定义它们自己的 Uri 属性。现在的代码: [] type UriUserControl() = inh
我正在构建一个项目,该项目从用户那里获取一个术语,然后执行谷歌搜索并返回一个 json 格式的标题列表。 我正在使用 serpwow API 来执行谷歌搜索并试图解析响应。 但是我收到的错误是: pa
我只想在其他接口(interface)中实现某些接口(interface),我不希望它们能够被类直接继承。 提前致谢! 最佳答案 您不能在 C# 中执行此操作 - 任何类都可以实现它有权访问的任何接口
我是 Go 的新手,还有一些我还没有掌握的技巧 例如,我有一个可以这样调用的函数: myVar.InitOperation("foo",Operator.EQUAL,"bar") myVar.Init
我有一个通用接口(interface)来描述对输出流的访问,如下所示: interface IOutput { function writeInteger(aValue:Int):Void;
我正在做一个项目,我想通过某种接口(interface)(最好是 USB)将光电探测器电路安装到计算机上。但是,由于我是新手,所以我不知道应该朝哪个方向处理这个问题。假设我有一个带有 USB 连接的光
背景 我正在尝试创建一个简单的应用程序,以真正理解DDD + TDD + etc的整个堆栈。我的目标是在运行时动态注入DAL存储库类。这让我 域和应用程序服务层可测试。我打算用“穷人的DI”来完成 现
在 Java 中,接口(interface)扩展接口(interface)是完全合法的。 UML 中的这种关系看起来像“扩展”关系(实线、闭合、未填充的箭头)还是“实现”关系(虚线、闭合、未填充的箭头
我想创建一个具有相等和比较函数默认实现的接口(interface)。 如果我从类型 IKeyable 中删除所有内容除了Key成员,只要我不添加默认实现,它就是一个有效的接口(interface)。从
COM 中的双接口(interface)是能够通过 DispInterface 或 VTable 方法访问的接口(interface)。 现在有人可以告诉我这两种方法之间到底有什么区别吗? 我认为 V
我有一个类方法,它返回一个可以迭代的员工列表。返回列表的最佳方式是什么?通常我只返回一个 ArrayList。然而,据我了解,界面更适合这种类型的操作。哪个是最好使用的界面?另外,为什么返回接口(in
我想从包装类外部实例化一个内部非静态接口(interface)。 这可能吗? 考虑以下代码: shared class AOuterClass() { Integer val = 3; shared
我为一个类编写了一个接口(interface),如下所示: public interface IGenericMultipleRepository { Lazy> addresses { ge
我是 UML 的初学者,现在我正在创建一个序列图,问题是我想根据用户输入实现 DAO 接口(interface)。如何在时序图中正确绘制以实现接口(interface)。 最佳答案 您不会在 SD 上
要使用 jsr 303 验证创建有条件验证的组,请将接口(interface)类传递给注释,如下所示: @NotEmpty (groups={UpdateValue.class}) 我有很多不同的接口
我是一名优秀的程序员,十分优秀!