通过混合静态和动态多态(模板和继承),我遇到了一种奇怪的技术,其功能与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 ++的规则,我没有看到它无法工作的原因。由于我似乎无法在任何地方找到它的名称,我将称之为“超多态”:)
答案 0 :(得分:8)
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
)时使用它。
它比常规继承更灵活,因为只需编写一个新类就可以扩展许多类的功能。
与“超多态性”不完全相同,但是,嘿,也许有一天会成为一件事。 ;)