【问题标题】:Function Overloading and returning different data types depending on the same input函数根据相同的输入重载和返回不同的数据类型
【发布时间】:2019-11-28 05:15:56
【问题描述】:

我还是 C++ 的新手,我知道我正在做的这个项目不应该用 C++ 编程,因为它很复杂,但我认为这将是学习一些细节的好方法。 C++ 之外。我有一个基类指针的存储向量,它们是指向多个不同派生类对象的指针。但是,我想找到最简单的方法来转换基类指针以使用派生类成员函数(从技术上讲,它们被切掉了,但我在推回带有派生的向量时使用“new”关键字类对象)。我和其他计算机科学同事谈过,他们说这是做我想做的事情(继承和多态)的最佳方式。我在基类中有几个变量,它们确定指针指向的派生类的类型,所以我可以毫不费力地弄清楚什么是什么,但是有没有可能找到一种方法将这些基类指针转换为自己的永久派生类?或者至少制作一个函数来快速转换每个指针(B2D)?有人告诉我也许可以使用函数重载。这是我认为会发生的事情的一个例子(但可能是非常错误的)

class base{

public:
std::string getdTypeName; // getter function for the variable
private:
std::string dTypeName;

}

class d1 : public base{

public:
//functions exclusive to d1
dTypeName=derived1;

}

class d2 : public base{

public:
//functions exclusive to d2
dTypeName=derived2;

}

class d3 : public base{

public:
//functions exclusive to d3
dTypeName=derived3;
}

std::vector<base*> storage; // these are randomly generated but for now this will do
storage.push_back(new d1);
storage.push_back(new d2);
storage.push_back(new d3);

if(storage[0]->getdTypeName()=="derived1"){
//static or dynamic cast as d1 object, or pointer? or something else?
}

if(storage[0]->getdTypeName()=="derived2"){
//same as above but with d2 object/pointer
}

if(storage[0]->getdTypeName()=="derived3"{
//same as above with d3 object/pointer
// do the above with each index?
}

知道我正在尝试编程的范围,我认为如果我必须检查每个索引的次数与派生类的次数一样多,我认为这并不重要,但是有没有更有效的方法来做B2D演员?每次我想做 B2D 演员时,我都必须这样做吗?如果是这样,是否可以将其浓缩为一个函数?我试图思考这个问题,我遇到的问题之一是返回类型,因为 dTypeName 决定了数据类型。我是否需要重载它三次,但根据 if 语句的结果返回不同的数据类型?提前致谢!

【问题讨论】:

  • 你为什么需要向下投射?通过virtual 方法使用多态。
  • learn how to ask。特别是“假装你在和一个忙碌的同事说话”和“拼写、语法和标点符号很重要!”

标签: c++ pointers inheritance polymorphism overloading


【解决方案1】:

你想要的可以使用虚函数来实现。

class Base
{
public:
  virtual void doSomething()
  {
    // base implementation
  }
};

class D1 : public Base
{
public:

  void doSomething() override
  {
    // D1 implmentation
  }
};

class D2 : public Base
{
public:

  void doSomething() override
  {
    // D2 implmentation
  }
};

在 main() 中,您现在可以在基指针上调用 doSomething 而不必担心它们的类型。

如果您仍想将转换作为学习练习,您可以使用 dynamic_cast,如果类型与实际存储的指针不匹配,它将返回 nullptr。

【讨论】:

    【解决方案2】:

    使用您的方法,您可以使用dynamic_cast

    struct base
    {
        virtual ~base() = default;
    };
    
    struct d1 : base {};
    struct d2 : base {};
    struct d3 : base {};
    
    void foo(base& b)
    {
        if (auto* d = dynamic_cast<d1*>(&b)) {
             std::cout << "derived 1\n";
        } else if (auto* d = dynamic_cast<d2*>(&b)) {
             std::cout << "derived 2\n";
        } else if (auto* d = dynamic_cast<d3*>(&b)) {
             std::cout << "derived 3\n";
        }
    }
    
    int main()
    {
        d1 o1;
        d2 o2;
        d3 o3;
        std::vector<base*> bases{&o1, &o2, &o3};
    
        for (auto* b : bases) {
            foo(*b);
        }
    }
    

    但最好使用虚方法:

    struct base
    {
        virtual ~base() = default;
        virtual void foo() = 0;
    };
    
    struct d1 : base { void foo() override { std::cout << "derived 1\n";} };
    struct d2 : base { void foo() override { std::cout << "derived 2\n";} };
    struct d3 : base { void foo() override { std::cout << "derived 3\n";} };
    
    int main()
    {
        d1 o1;
        d2 o2;
        d3 o3;
        std::vector<base*> bases{&o1, &o2, &o3};
    
        for (auto* b : bases) {
            b->foo();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多