Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 静态多态性对实现接口有意义吗?_C++_Templates_Polymorphism_Static Polymorphism_Policy Based Design - Fatal编程技术网

C++ 静态多态性对实现接口有意义吗?

C++ 静态多态性对实现接口有意义吗?,c++,templates,polymorphism,static-polymorphism,policy-based-design,C++,Templates,Polymorphism,Static Polymorphism,Policy Based Design,祝大家圣诞快乐 我正在学习静态多态性,正在阅读Andrei Alexandrescu关于基于策略的设计的优秀著作。在我的代码中,我遇到了以下问题:我有接口interface,它指定方法Foo必须存在。此接口将由类Impl实现。我有以下两个选择: 1) 动态多态性 class Interface { public: virtual void Foo() = 0; } class Impl : public Interface { public: void Foo() {}; }

祝大家圣诞快乐

我正在学习静态多态性,正在阅读Andrei Alexandrescu关于基于策略的设计的优秀著作。在我的代码中,我遇到了以下问题:我有接口
interface
,它指定方法
Foo
必须存在。此接口将由类
Impl
实现。我有以下两个选择:

1) 动态多态性

class Interface {
public:
    virtual void Foo() = 0;
}

class Impl : public Interface {
public:
    void Foo() {};
}
class Impl {
{
public:
    void Foo() {};
}

template <class I>
class Interface : public I
{
public:
    void Foo() { I::Foo(); } //not actually needed
}
2) 静态多态性

class Interface {
public:
    virtual void Foo() = 0;
}

class Impl : public Interface {
public:
    void Foo() {};
}
class Impl {
{
public:
    void Foo() {};
}

template <class I>
class Interface : public I
{
public:
    void Foo() { I::Foo(); } //not actually needed
}
class Impl{
{
公众:
void Foo(){};
}
模板
类接口:public I
{
公众:
void Foo(){I::Foo();}//实际上不需要
}
在这种情况下使用静态多态性有意义吗?与第一种方法相比,第二种方法有什么好处吗?接口只指定了一些方法的存在,并且它的机制对于不同的实现是相同的-因此与书中描述的情况不太像,所以我觉得我可能只是过于复杂了t欣


更新:我在运行时不需要多态行为;正确的实现在编译时是已知的。

使用静态多态性是否有意义取决于您如何使用该类

虚拟函数引入了一个间接级别。虚拟函数允许使用基类对象(所有派生类通用)的指针或引用调用派生类中的方法

静态polimorphism不使用公共基类。每个派生类都使用自己的基类。这些基类通常是从公共类模板创建的。然而,它们是不同的类。这会导致这样的情况,例如指向此类对象的指针或引用无法存储在公共容器中。

检查接口。 动态多态性确实迫使子对象尊重接口

静态多态性不会强制子级尊重接口 (直到你真正调用函数),所以,如果你没有提供有用的方法, 您可以直接使用
Impl

class InvalidImpl {}; // Doesn't respect interface.
void bar()
{
    InvalidImpl invalid;

    // this compiles, as not "expected" since InvalidImpl doesn't respect Interface.
    CRTP_Interface<InvalidImpl> crtp_invalid; 

#if 0 // Any lines of following compile as expected.
    invalid.Foo();
    crtp_invalid.Foo();
#endif
}
但它无法在以下情况下发挥任何魔力(假设
bar
未内联):

现在,假设您的界面中有:

void Interface::Bar() { /* some code */ Foo(); }
在第二种情况下,我们必须虚拟调用
Foo

静态多态性通过以下方式解决此问题:

template<class Derived>
void Interface<Derived>::Bar() { /* some code */ static_cast<Derived*>(this)->Foo(); }
模板
void接口::Bar(){/*一些代码*/static_cast(this)->Foo();}

第二种方法与第二种方法相比毫无益处。-()查看维基的优点和缺点:你是想了解如何从java接口转换到C++吗?不,我不懂java。你可以使用<代码>接口::();
在第一个示例中,对基类的调用没有任何区别。但是当您有多个实现Foo函数的基类时,第二个解决方案有一个好处。如果是这样,在使用子类时,可以通过这样做来选择正确的基类:
Interf
在我的示例中,接口类是派生的class(对于静态示例)。在这两种情况下,我都可以调用
Interface.Foo()
@DanNestor No。在您的示例中,您将有
Interface.Foo()
Interface.Foo()
但是
接口
接口
是两个不同的类。你不能将
接口
存储在
std::vector
中,反之亦然。哦,我理解,谢谢。但是,我在运行时不需要多态行为,我会更新这个问题。非常好的一点“指向此类对象的指针或引用不能存储在公共容器中。”。以前没有从该角度考虑过。使用以下方法检查接口如何:
使用派生::func
void bar(Interface& child) { child.Foo(); } // have to virtual call Foo.
void Interface::Bar() { /* some code */ Foo(); }
template<class Derived>
void Interface<Derived>::Bar() { /* some code */ static_cast<Derived*>(this)->Foo(); }