通过混合静态和动态多态性(模板和继承),我遇到了一种奇怪的技术,其功能与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++的规则,但我看不出它不起作用的原因。由于我似乎无法在任何地方找到它的名称,因此我将这种技术称为“ super 多态” :)
最佳答案
编辑:对不起,我误解了OPs代码的重要组成部分。真可惜删除了我回答的错误部分。但是,以下内容仍然成立...
恕我直言,您的比较不公平
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
与
Base* cx1 = new ClassX<Class1>();
//cout << cx1->x << endl; // Wont work as well !!!
(例如,请参见here)或
Class2 c2;
cout << c2.y << endl; // Works of course
与
ClassX<Class1> cx1;
cout << cx1.x << endl; // Works of course as well !!!
也就是说,该技术可能有其应用。例如,您在注释中提到的情况,当您需要向许多不同的基类添加相同的功能时。
Afaik没有为此命名。就像其他人在评论中提到的那样,这些用途是用相同的功能来装饰许多不同的类。
我必须承认,只有在@Amadeus指出我的答案的一半是错误的之后,我才完全理解OPs代码中的方法。恕我直言,这是一项相当大的努力(两次继承加上一个模板),但并没有获得太多 yield ,也许这就是为什么它不是一种众所周知且普遍采用的技术的原因。尽管在某些特殊情况下可能很有用。