【问题标题】:how to refer to a base class's derived class?如何引用基类的派生类?
【发布时间】:2019-04-05 00:09:29
【问题描述】:
class Element { };
class Container {
    vector<Element*> elements;
};

以上是原始代码。我被告知不要更改上面的代码。现在我有

class IndexElement: public Element {
    int b_index;
};

class Container* ctr;

现在我有ctr-&gt;elements。但是Element 没有成员b_index。有什么简单的方法可以将elements 的归属从Element 重定向到IndexElement?提前致谢!

【问题讨论】:

  • 你不能。基类不知道它被用作基类。
  • “有什么简单的方法可以将 a2b 的属性从 b 重定向到 bson?” 除非你使用明确的接口没有。此外,ason 的实例永远无法正确转换为 bson
  • 我认为这是如何访问存储在a2b 中的对象中的成员。不将ason 转换为bson
  • 原始代码不会编译,所以你可以把它扔掉(或显示真实代码)。
  • 我认为,代码非常复杂,没有任何原因。我将进行编辑以减少复杂性,但表达相同的想法。

标签: c++ stl static-cast


【解决方案1】:

您有一个选择:您知道向量中有IndexElement 而不是Element,然后您可以使用static_cast&lt;IndexElement*&gt;(elements[i]);。请注意,如果您没有只有 IndexElement,那么这将完全崩溃。

如果您可以修改 b,那么您还有另一种选择,将 b 设为虚拟。如果您不知道,您可能有Elements 和IndexElements,在这种情况下使用dynamic_cast&lt;IndexElement*&gt;(elements[i]); 并对其进行测试,结果是否为nullptr。在这种情况下,b 必须是虚拟的(因此是虚拟析构函数)。

(我假设我们在Container,所以直接访问它的成员)

使用修改后的元素进行完整试用(由于未分配 elements 而将中断):

#include <vector>

using namespace std;

class Element{
public:
    virtual ~Element() {}
};

class Container{
    public:
vector<Elements*>elements;
};

class IndexElement: public Element{
int index;
};

int main()
{
    Container aa;
    static_cast<IndexElement*>(aa.elements[0]);
    dynamic_cast<IndexElement*>(aa.elements[0]);
    return 0;
}

【讨论】:

    【解决方案2】:

    好吧,即使没有虚拟和 RTTI(动态转换),您仍然可以选择跟踪和检查创建的 IndexElement 实例,例如:

    std::unordered_set<Element *> idxElemSet;
    
    class IndexElement: public Element {
        int b_index;
    public:
        IndexElement(int index) : b_index(index)
        { idxElemSet.insert(this); }
    
        IndexElement(const IndexElement& other) : b_index(other.b_index)
        { idxElemSet.insert(this); }
    
        // might also need the move constructor in case of c++11
    
        ~IndexElement()
        { idxElemSet.erase(this); }
    
    };
    
    int main()
    {
        Container c;
        ...
        Element* e = c.elements[0];
    
        if (idxElemSet.find(e) != idxElemSet.end()) {
            IndexElement* ie = static_cast<IndexElement*>(e);
            // do something with ie->b_index
        }
    
        return 0;
    }
    

    所以你基本上可以保留所有创建的实例的地址集,并且在检查特定实例时,只需检查当前对象地址是否在集合中。

    idxElemSetIndexElement 内部也可以是静态的,并且类本身可能只提供静态转换功能,在内部进行检查和转换等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-01
      • 2013-12-19
      • 2011-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多