简体   繁体   English

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

[英]C++ Combining Static and Dynamic Polymorphism to Create “Hyper Polymorphism”?

By mixing both static and dynamic polymorphism (templates and inheritance) I have come across a strange technique that functions similarly to regular static polymorphism in C++, except the members of the child class are still visible after creating the new object. 通过混合使用静态和动态多态(模板和继承),我遇到了一种奇怪的技术,其功能类似于C ++中的常规静态多态,除了在创建新对象后子类的成员仍然可见。

Consider the following example: 请考虑以下示例:


Base.h: Base.h:

#include <iostream>

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

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

Class1.h: 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: 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;
};

This is where things get interesting... 事情变得有趣......

ClassX.h ClassX.h

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

By implementing classX in such a way that it can dynamically inherit from anything it allows some strange things to occur. 通过以这样的方式实现classX,它可以动态地从任何东西继承它允许发生一些奇怪的事情。 See the example below showing it in use. 请参阅下面的示例,显示它正在使用中。

main.cpp 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;
}

What I'm wondering is why have I never seen this technique before? 我想知道为什么我以前从未见过这种技术? I've never once seen anyone try to inherit from an unknown class using templates like this: 我从来没有见过有人尝试使用这样的模板继承未知类:

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

Is there a name to this technique, and what are it's uses? 这种技术有名称,它的用途是什么?

I just gave it a try because knowing the rules of C++ I didn't see a reason why it wouldn't work. 我只是试一试,因为我知道C ++的规则,我没有看到它为什么不起作用的原因。 Since I can't seem to find a name for it anywhere I'm going to call this technique "Hyper Polymorphism" :) 因为我似乎无法在任何地方找到它的名称,我将称之为“超多态”:)

EDIT: sorry misunderstood an important part of OPs code. 编辑:抱歉误解了OP代码的重要部分。 Shame on me. 对我感到羞耻。 Removed the wrong part of my answer. 删除了我的答案的错误部分。 However, the following still holds... 但是,以下仍然有......

Imho your comparison isnt fair 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!

These are two completely different cases. 这是两个完全不同的案例。 A fair comparison would be 公平的比较是

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

vs VS

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

(see here for an example) or (见这里的例子)或

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

vs VS

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

That said, this technique might have its applications. 也就是说,这种技术可能有它的应用。 For example the case you mentioned in a comment, when you need to add the same functionality to many differnt base classes. 例如,当您需要向许多不同的基类添加相同的功能时,您在注释中提到的情况。

Is there a name to this technique, and what are it's uses? 这种技术有名称,它的用途是什么?

Afaik there isnt a name for this. Afaik没有这个名字。 The uses are, as others have mentioned in comments, to decorate many different classes with the same functionality. 正如其他人在评论中提到的那样,这些用途是用相同的功能来装饰许多不同的类。

I have to admit that only after @Amadeus pointed out that half of my answer was wrong, I fully understood the approach in OPs code. 我必须承认,只有在@Amadeus指出我的答案的一半是错误的之后,我才完全理解OPs代码中的方法。 Imho it is quite some effort (twice inheriting plus a template) for not too much gain, and maybe thats the reason why it isnt a well known and commonly applied technique. 虽然这不是一个众所周知且常用的技术,但它是相当多的努力(两次继承加上一个模板)而不是太多的收益。 Though it might be useful in some special cases. 虽然它在某些特殊情况下可能有用。

From reading the comments it looks like this technique is actually considered a " decorator pattern ". 从阅读评论看起来这种技术实际上被认为是“ 装饰模式 ”。

It can be used when you need to extend the functionality of multiple existing classes (for example adding a member variable z ) when you can't modify the classes directly. 当您无法直接修改类时,可以在需要扩展多个现有类的功能(例如添加成员变量z )时使用它。

It's more flexible than regular inheritance because you can extend the functionality of many classes by only writing one new class. 它比常规继承更灵活,因为只需编写一个新类就可以扩展许多类的功能。

Not exactly the same as "hyper polymorphism", but hey, maybe that will be a thing some day. 与“超多态性”不完全相同,但是嘿,也许有一天会成为一件事。 ;) ;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM