首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于子类型的C++结构动态转换

基于子类型的C++结构动态转换
EN

Stack Overflow用户
提问于 2016-04-20 07:01:56
回答 2查看 4K关注 0票数 1

因此,我目前正在尝试创建自己的易用性组件体系结构,并且我遇到了一些问题。

我将我的组件存储为一个结构,如

代码语言:javascript
复制
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。这是我今天上传的另一个问题的转贴。这是一个重复的问题,但这个重复甚至没有回答我的问题。我请求你通过评论来理解我问题的正确性,而不是阻止别人帮助我。谢谢。

EN

回答 2

Stack Overflow用户

发布于 2016-04-20 10:05:40

您可以获得有关具有RTTI的变量类型的信息,如:

代码语言:javascript
复制
 (typeid(*baseComp) == typeid(ComponentB))

这在你的例子中是正确的。

票数 2
EN

Stack Overflow用户

发布于 2016-04-20 09:46:15

或者,你也可以这样做。这并不像霍尔特的回答那么专业,但它也有同样的缺点。稍后再谈他们。

代码语言:javascript
复制
#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++11smart pointer编写了代码。如果你没有与C++11合作-检查它,你会喜欢它。

为什么这个代码不像霍尔特的代码那么专业?

因为它依赖于简单的int值,而不是类型和强制转换,这些值专门用于标识类型。

不过,我认为主要的问题是完全不同的:

这两种代码的缺点是什么?

在这两种代码中,客户端必须知道所有派生类。在霍尔特的回答中,这是if statements的一部分。在我的回答中,这是switch statement

如果有新的派生类Derived3,会发生什么?您需要更改客户端代码。

我相信您可以使用多态来完成这个任务,并且只可以使用Base类,而不需要任何类型的转换。

示例

有很多这样的例子-数字,人(学生,教授),汽车(运动,皮卡,suv,卡车)。这正是我最喜欢的:

代码语言:javascript
复制
#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
}

在许多面向对象语言(如JavaC#PHP )中,基类Shape被称为interface。注意它如何定义方法,但不包括任何实现细节。

这允许在不同的编译单元中实现派生类,并且客户端代码不知道它使用的是哪个类。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36736167

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档