因此,我目前正在尝试创建自己的易用性组件体系结构,并且我遇到了一些问题。
我将我的组件存储为一个结构,如
struct BaseComponent
{
bool isValid;
}
struct ComponentA : BaseComponent
{
int someValForA;
}
struct ComponentB : BaseComponent
{
int someValForB
}
ComponentB* compB = new ComponentB()
compB->someValForB = 10;
BaseComponent* baseComp = compB
ComponentB* comp = (ComponentB*) baseComp我希望我的系统能够存储渐变继承的结构。所以我需要用一个指针向量。问题是,如何在不知道它们的原派生子类型的情况下,动态地将它们转换回原派生结构?我可以通过没有枚举的代码来确定它们的派生类型,因为我想在库中实现它。
我也将采取的答案,也给出了实施这一系统的替代办法,同时铭记,我想发展它。如果可能,请提供一个代码示例来帮助您。
谢谢你的阅读:)
PS。这是我今天上传的另一个问题的转贴。这是一个重复的问题,但这个重复甚至没有回答我的问题。我请求你通过评论来理解我问题的正确性,而不是阻止别人帮助我。谢谢。
发布于 2016-04-20 10:05:40
您可以获得有关具有RTTI的变量类型的信息,如:
(typeid(*baseComp) == typeid(ComponentB))这在你的例子中是正确的。
发布于 2016-04-20 09:46:15
或者,你也可以这样做。这并不像霍尔特的回答那么专业,但它也有同样的缺点。稍后再谈他们。
#include <iostream>
#include <memory>
struct Base {
virtual int what() const = 0;
virtual ~Base(){}
};
struct Derived1 : Base {
static constexpr int ME = 1;
int what() const{
return ME;
}
};
struct Derived2 : Base {
static constexpr int ME = 2;
int what() const{
return ME;
}
};
using pBase = std::unique_ptr<Base>;
void doSomething(pBase &base){
switch(base->what()){
case Derived1::ME :
std::cout << "Derived1" << std::endl;
break;
case Derived2::ME :
std::cout << "Derived2" << std::endl;
break;
default:
std::cout << "huh?" << std::endl;
}
}
int main(){
pBase base1{ new Derived1() };
pBase base2{ new Derived2() };
doSomething(base1);
doSomething(base2);
//no need to call delete
}我使用C++11和smart pointer编写了代码。如果你没有与C++11合作-检查它,你会喜欢它。
为什么这个代码不像霍尔特的代码那么专业?
因为它依赖于简单的int值,而不是类型和强制转换,这些值专门用于标识类型。
不过,我认为主要的问题是完全不同的:
这两种代码的缺点是什么?
在这两种代码中,客户端必须知道所有派生类。在霍尔特的回答中,这是if statements的一部分。在我的回答中,这是switch statement。
如果有新的派生类Derived3,会发生什么?您需要更改客户端代码。
我相信您可以使用多态来完成这个任务,并且只可以使用Base类,而不需要任何类型的转换。
示例
有很多这样的例子-数字,人(学生,教授),汽车(运动,皮卡,suv,卡车)。这正是我最喜欢的:
#include <iostream>
#include <memory>
struct Shape {
virtual float area() const = 0;
virtual const char *name() const = 0;
virtual ~Shape(){}
};
struct Square : Shape {
Square(float a) : a(a){
}
const char *name() const override{
return "Quadrat"; // this has nothing to do with class name
}
float area() const override{
return a * a;
}
private:
float a;
};
struct Circle : Shape {
Circle(float r) : r(r){
}
const char *name() const override{
return "Circle";
}
float area() const override{
return PI * r * r;
}
private:
constexpr static float PI = 3.14159;
float r;
};
using pShape = std::unique_ptr<Shape>;
void doSomething(pShape &base){
std::cout << base->name()
<< " has area of "
<< base->area()
<< "m2"
<< std::endl;
}
int main(){
pShape base1{ new Square(5) };
pShape base2{ new Circle(5) };
doSomething(base1);
doSomething(base2);
//no need to call delete
}在许多面向对象语言(如Java、C#或PHP )中,基类Shape被称为interface。注意它如何定义方法,但不包括任何实现细节。
这允许在不同的编译单元中实现派生类,并且客户端代码不知道它使用的是哪个类。
https://stackoverflow.com/questions/36736167
复制相似问题