使用数组对对象的编译时多态性是否可行?
Is Compile Time Polymorphism Of Objects Using Arrays Possible?
我还在学习,我有一个问题,希望有人能帮助我:
是否可以在不使用虚函数的情况下实现从同一基类继承的不同类的编译时多态性,以便在数组中使用?
作为任何知道一点 OOP 的人,如果你有类似的东西,C++
class Base {
public:
virtual void foo (){
std::cout << "I'm the base" << std::endl;
}
}
class A : public Base {
public:
void foo() {
std::cout << "I'm the child" << std::endl;
}
}
class B : public Base {
public:
void foo() {
std::cout << "I'm the child #2" << std::endl;
}
}
//Assume some main here
A *a = new A();
B *b = new B();
Base *someArray[] = {a,b};
someArray[0]->foo(); //"I'm the child"
someArray[1]->foo(); //"I'm the child #2"
我们知道这是有效的,因为函数是和继承在运行时解析的。但是,我要知道的是如何在没有虚函数的情况下做到这一点,或者是否可以在不使用虚函数的情况下做同样的事情?
假设你做这样的事情
class Base {
public:
void foo (){
std::cout << "I'm the base" << std::endl;
}
}
class A : public Base {
public:
void foo() {
std::cout << "I'm the child" << std::endl;
}
}
class B : public Base {
public:
void foo() {
std::cout << "I'm the child #2" << std::endl;
}
}
//Assume some main here
A *a = new A();
B *b = new B();
Base *someArray[] = {a,b};
someArray[0]->foo(); //"I'm the base"
someArray[1]->foo(); //"I'm the base"
所以有很多选择,但我似乎找不到具有我想要的相同行为的东西。我读到的一个解决方案是制作一个静态类模板,其工作方式如下
template <class T>
class Base
{
public:
void interface()
{
// ...
static_cast<T*>(this)->implementation();
// ...
}
static void static_func()
{
// ...
T::static_sub_func();
// ...
}
};
class Derived : Base<Derived>
{
public:
void implementation() {
std::cout << "I am derived" << std::endl;
}
static void static_sub_func();
};
class AlsoDerived : Base<Derived>
{
public:
void implementation() {
std::cout << "I am also derived" << std::endl;
}
static void static_sub_func();
};
//Assume in some main
Derived div;
AlsoDerived alsoDiv;
Derived *someArray[] = { &div, &alsoDiv };//does not work not the same type
Base *someArray[] = { &div, &alsoDiv }; //does not work b/c its a template
以上不是我想要的行为。然后是静态转换,这似乎很有前途,但是我需要知道在任何给定时间它会是什么类,这不是我想要的行为。
class Base {
public:
void foo (){
std::cout << "I'm the base" << std::endl;
}
}
class A : public Base {
public:
void foo() {
std::cout << "I'm the child" << std::endl;
}
}
class B : public Base {
public:
void foo() {
std::cout << "I'm the child #2" << std::endl;
}
}
//Assume some main here
A *a = new A();
A *b = new A();
B *c = new B();
Base *someArray[] = {a,b,c};
someArray[0]->foo(); //"I'm the base"
static_cast<A*>(someArray[1])->foo(); //"I'm the child"
static_cast<B*>(someArray[2])->foo(); //"I'm the child #2"
这非常接近我想要的,但是我的问题是要使static_cast工作,我需要知道我想要静态大小写的是什么类,而不是我想要的行为。
你觉得怎么样?有没有更好的方法做我想做的事?
感谢您的阅读,如果对我所问的内容有任何困惑,请告诉我,以便我澄清。
在编译时没有真正的方法可以做你想做的事情。 仅仅因为您希望您的行为取决于运行时对象的类型。
C++通过多态性(即使用虚函数)和 RTTI(如果需要)提供运行时类型依赖行为。 如果您不想使用这种"自然方式",您将有以下选择:
- 你知道编译时对象的类型(例如,如果你确定第一个元素始终是
A*
,第二个元素始终是B*
):在这种情况下,您可以使用static_cast
,就像在第三种情况下一样,或者使用模板化代码(例如,如果您更喜欢编译时策略而不是运行时策略)。 但这通常不是处理容器中随机对象的方法。 - 您可以自己找出对象的类型并推断出要调用的相应函数: 执行此操作的典型方法是在基类中有一个键入字段,并使用它来向下转换
static_cast
。但这不是最佳做法。 添加自己的类似RTTI的功能而不是使用编译器的优化功能不会比多态更有效。 - 您可以使用
std::variant
或std::any
:这些提供了使用编译时功能提供某种运行时相关行为的可能性(不一定要求从公共基派生替代类型)。
剩下的问题是,如果需要,为什么要避免正常的多态性。
相关文章:
- 多态性和功能结合
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- C++boost序列化多态性问题
- 如何查找哪个类对象位于数组的特定索引上(多态性)
- 如何在多线程中正确使用unique_ptr进行多态性?
- 具有智能指针的多态性
- 继承/多态性 - 我是否被迫使用"protected"变量?
- C++多态性:如何测试一个类是否派生自另一个基类
- C++ 多态性:如果派生类中的虚函数在基类中声明了常量,是否需要将其声明为常量
- 在 PHP 中不使用父类时是否称为多态性
- 多态性是否适用于值?或者在按(基)值返回时使用派生类的移动构造函数
- 使用数组对对象的编译时多态性是否可行?
- CRTP 静态多态性:是否可以用模拟替换基类
- 是否可以将多态性类存储在共享内存中
- 方法重写(没有虚拟方法或指针)是否被认为是多态性的一部分
- c++:多态性+多重继承顺序.继承顺序是否重要
- 是否可以为模板化的基类提供专门的类层次结构,但仍利用它们之间的多态性
- "delete"多态性是否正常工作?
- 重载父函数是否会规避多态性?