C ++结合静态和动态多态来创建“超多态”?

时间:2017-05-09 19:38:23

标签: c++ templates inheritance polymorphism

通过混合静态和动态多态(模板和继承),我遇到了一种奇怪的技术,其功能与C ++中的常规静态多态相似,除了在创建新对象后子类的成员仍然可见。

请考虑以下示例:

Base.h:

#include <iostream>

class Base {
public:
    virtual ~Base() {}

    virtual void say_hello() {
        std::cout << "Hello from Base!" << std::endl;
    }
};

Class1.h:

#include "Base.h"
#include <iostream>

class Class1 : public Base {
public:
    virtual void say_hello() {
        std::cout << "Hello from Class1!" << std::endl;
    }

    int x = 1;
};

Class2.h:

#include "Base.h"
#include <iostream>

class Class2 : public Base {
public:
    virtual void say_hello() {
        std::cout << "Hello from Class2!" << std::endl;
    }

    int y = 2;
};

这是事情变得有趣的地方......

ClassX.h

template <class T>
class ClassX : public T {
public:
    int z = 3;
};

通过实现classX,它可以动态地从任何东西继承,它允许发生一些奇怪的事情。请参阅下面显示正在使用的示例。

的main.cpp

#include <iostream>
#include "Base.h"
#include "Class1.h"
#include "Class2.h"
#include "ClassX.h"

using namespace std;

int main(int argc, char* argv[]) {

    Base* b = new Base;
    b->say_hello();

    // Regular polymorphism in action
    Base* c1 = new Class1;
    c1->say_hello();         // Aware that this is Class1
    //cout << c1->x << endl; // Doesn't work! Not visible from here

    Base* c2 = new Class2;
    c2->say_hello();         // Aware that this is Class2
    //cout << c2->y << endl; // Doesn't work! Not visible from here

    // Hyper polymorphism!? Not sure what to call this.
    ClassX<Class1> cx1;
    cx1.say_hello();       // Aware that this is Class1
    cout << cx1.x << endl; // The member variable is visible!
    cout << cx1.z << endl; // Also available :)

    ClassX<Class2> cx2;
    cx2.say_hello();       // Aware that this is Class2
    cout << cx2.y << endl; // The member variable is visible!
    cout << cx2.z << endl; // Also available :)

    // ALWAYS delete objects created with "new" or shame on yew.
    delete b;
    delete c1;
    delete c2;
}

我想知道为什么以前从未见过这种技术?我从来没有见过有人试图使用这样的模板继承未知类:

template <class T>
class Name : public T {
    // Implementation
};

此技术是否有名称,有什么用途?

我只是试一试,因为我知道C ++的规则,我没有看到它无法工作的原因。由于我似乎无法在任何地方找到它的名称,我将称之为“超多态”:)

2 个答案:

答案 0 :(得分:8)

编辑:抱歉误解了OP代码的一个重要部分。对我感到羞耻。删除了我的答案的错误部分。但是,以下仍然有......

Imho你的比较是不公平的

Base* c2 = new Class2;
//cout << c2->y << endl; // Doesn't work! Not visible from here

ClassX<Class1> cx1;
cout << cx1.x << endl; // The member variable is visible!

这是两个完全不同的案例。公平的比较是

Base* c2 = new Class2;
//cout << c2->y << endl; // Doesn't work! Not visible from here

VS

Base* cx1 = new ClassX<Class1>();
//cout << cx1->x << endl; // Wont work as well !!!

(有关示例,请参阅here)或

Class2 c2;
cout << c2.y << endl; // Works of course

VS

ClassX<Class1> cx1;
cout << cx1.x << endl; // Works of course as well !!!

那就是说,这种技术可能有它的应用。例如,当您需要向许多不同的基类添加相同的功能时,您在注释中提到的情况。

  

这种技术有名称,它的用途是什么?

Afaik没有这个名字。正如其他人在评论中提到的那样,这些用法是用相同的功能来装饰许多不同的类。

我必须承认,只有在@Amadeus指出我的答案的一半是错误的之后,我才完全理解OPs代码中的方法。虽然这不是一个众所周知且常用的技术,但它是相当多的努力(两次继承加上一个模板)而不是太多的收益。虽然它在某些特殊情况下可能有用。

答案 1 :(得分:3)

从阅读评论看起来,这种技术实际上被认为是“decorator pattern”。

当您无法直接修改类时,可以在需要扩展多个现有类的功能(例如添加成员变量z)时使用它。

它比常规继承更灵活,因为只需编写一个新类就可以扩展许多类的功能。

与“超多态性”不完全相同,但是,嘿,也许有一天会成为一件事。 ;)