静态多态:如何定义接口?
Static polymorphism: How to define the interface?
下面是我理解的静态多态性的一个非常简单的例子。我不使用动态多态性的原因是我不想阻碍 op
.
中 PROCESSOR
函数的内联
template <class PROCESSOR>
void op(PROCESSOR* proc){
proc->doSomething(5);
proc->doSomethingElse();
}
int main() {
ProcessorY py;
op<ProcessorY>(&py);
return 0;
}
这个例子的问题是:没有明确定义 PROCESSOR
必须定义的函数。如果缺少一个,你只会得到一个编译错误。我认为这是一种糟糕的风格。
它还有一个非常实际的缺点:IDE 的在线帮助当然不能向您显示该对象上可用的功能。
定义 PROCESSOR
的 public 接口的 good/official 方法是什么?
首先,我认为你的静态多态性例子没有问题。由于它是静态的,即编译时解析,根据定义,它对其接口定义的要求不那么严格。
此外,不正确的代码不会compile/link也是绝对合法的,尽管来自编译器的更清晰的错误消息会更好。
但是,如果您坚持接口定义,您可以按以下方式重写您的示例:
template <class Type>
class Processor
{
public:
void doSomething(int);
void doSomethingElse();
};
template <class Type>
void op(Processor<Type>* proc){
proc->doSomething(5);
proc->doSomethingElse();
}
// specialization
template <>
class Processor<Type_Y>
{
// implement the specialized methods
};
typedef Processor<Type_Y> ProcessorY;
int main() {
ProcessorY py;
op(&py);
return 0;
}
There exists no explicit definition of what methods a PROCESSOR has to define. If one is missing, you will just get a compile error. I think, this is bad style.
是的。它不是。可能是。这取决于。
是的,如果您想以这种方式定义行为,您可能还想限制模板参数应该具有的内容。不幸的是,现在无法执行此操作 "explicitly"。
您想要的是 constraints and concepts 功能,它应该作为 C++ 11 的一部分出现,但被延迟并且从 C++ 14 开始仍然不可用。
然而,获取编译时错误通常是限制模板参数的最佳方式。例如,我们可以使用 std
library:
1) 迭代器。
C++ 库 defines 几种类型的迭代器:forward_iterator
、random_access_iterator
等。对于每种类型,都定义了一组属性和有效表达式,保证可用。如果您使用迭代器,它与容器中的 random_access_iterator
不完全兼容,需要 random_access_iterator
,您将在某些时候遇到编译器错误(最有可能的是,在使用解引用运算符 ([]) 时,这是在此迭代器中需要 class).
2) 分配器。
std
库中的所有容器都使用分配器来执行内存 allocation/deallocation 和对象构造。默认情况下,使用 std::allocator。如果你想用你自己的交换它,你需要确保它拥有一切,std::allocator
保证拥有。否则,你会得到编译时错误。
因此,在我们获得概念之前,这是最好且使用最广泛的解决方案。
下面是我理解的静态多态性的一个非常简单的例子。我不使用动态多态性的原因是我不想阻碍 op
.
PROCESSOR
函数的内联
template <class PROCESSOR>
void op(PROCESSOR* proc){
proc->doSomething(5);
proc->doSomethingElse();
}
int main() {
ProcessorY py;
op<ProcessorY>(&py);
return 0;
}
这个例子的问题是:没有明确定义 PROCESSOR
必须定义的函数。如果缺少一个,你只会得到一个编译错误。我认为这是一种糟糕的风格。
它还有一个非常实际的缺点:IDE 的在线帮助当然不能向您显示该对象上可用的功能。
定义 PROCESSOR
的 public 接口的 good/official 方法是什么?
首先,我认为你的静态多态性例子没有问题。由于它是静态的,即编译时解析,根据定义,它对其接口定义的要求不那么严格。
此外,不正确的代码不会compile/link也是绝对合法的,尽管来自编译器的更清晰的错误消息会更好。
但是,如果您坚持接口定义,您可以按以下方式重写您的示例:
template <class Type>
class Processor
{
public:
void doSomething(int);
void doSomethingElse();
};
template <class Type>
void op(Processor<Type>* proc){
proc->doSomething(5);
proc->doSomethingElse();
}
// specialization
template <>
class Processor<Type_Y>
{
// implement the specialized methods
};
typedef Processor<Type_Y> ProcessorY;
int main() {
ProcessorY py;
op(&py);
return 0;
}
There exists no explicit definition of what methods a PROCESSOR has to define. If one is missing, you will just get a compile error. I think, this is bad style.
是的。它不是。可能是。这取决于。
是的,如果您想以这种方式定义行为,您可能还想限制模板参数应该具有的内容。不幸的是,现在无法执行此操作 "explicitly"。
您想要的是 constraints and concepts 功能,它应该作为 C++ 11 的一部分出现,但被延迟并且从 C++ 14 开始仍然不可用。
然而,获取编译时错误通常是限制模板参数的最佳方式。例如,我们可以使用 std
library:
1) 迭代器。
C++ 库 defines 几种类型的迭代器:forward_iterator
、random_access_iterator
等。对于每种类型,都定义了一组属性和有效表达式,保证可用。如果您使用迭代器,它与容器中的 random_access_iterator
不完全兼容,需要 random_access_iterator
,您将在某些时候遇到编译器错误(最有可能的是,在使用解引用运算符 ([]) 时,这是在此迭代器中需要 class).
2) 分配器。
std
库中的所有容器都使用分配器来执行内存 allocation/deallocation 和对象构造。默认情况下,使用 std::allocator。如果你想用你自己的交换它,你需要确保它拥有一切,std::allocator
保证拥有。否则,你会得到编译时错误。
因此,在我们获得概念之前,这是最好且使用最广泛的解决方案。