【问题标题】:dereferencing in a vector of pointers to objects在指向对象的指针向量中解引用
【发布时间】:2010-06-22 04:02:11
【问题描述】:

我正在尝试访问由向量容器中保存的指针指向的对象(称为向量),但我似乎无法访问它。

这里是重要的代码sn-ps:

int main{
    Vector<double>* test = new Vector<double>(randvec<double>());

    test->save();

    cout << Element::vectors[0];
return 0;
}

其中Vector是一个模板类,randvec&lt;T&gt;()返回一个向量的引用,save()

template <class T>
void Vector<T>::save()
{
    vectors.push_back(this);
}

vectors 是 Vectors 的基类 Element.h 中定义的static std::vector&lt;Element*&gt; vectors;

这一切都错了吗?我试图通过使用指向主类的指针向量将派生类的所有元素包含在基类的静态数据成员中。

main() 的输出可能会告诉你发生了什么——我得到了指针0x1001000a0。但是,如果我尝试取消引用该指针,则会收到以下错误:

error: no match for 'operator<<' in 'std::cout << * Element::vectors. 
std::vector<_Tp, _Alloc>::operator[] [with _Tp = Element*, _Alloc = std::allocator<Element*>](0ul)'

为什么我不能取消引用这个指针?

【问题讨论】:

  • 为什么要动态分配呢? (提示:你在泄漏!)
  • 我花了三遍阅读您的描述才知道您命名的不同部分是如何相互纠缠的!这真的需要两期建设吗?如果所有对象都存储在基类静态数据成员中,为什么不将它们存储在它们的构造函数中呢?为什么要为test 使用动态分配?你在泄露它。自动对象有什么问题?哦,在 C++ 中 file != class.

标签: c++ pointers reference vector dereference


【解决方案1】:

问题不在于取消引用。问题是没有为 Element::vectors 定义“

【讨论】:

    【解决方案2】:

    您似乎缺少可用于输出Elementoperator&lt;&lt; 重载。请注意,如果您只为 Vector&lt;T&gt; 定义重载,它将不起作用,因为取消引用 Element::vectors[0] 会为您提供 Element 类型的对象。

    这是一个(未经测试,抱歉)示例,说明如何允许派生类(如Vector&lt;T&gt;)覆盖Element 的流插入行为:

    Element添加一个虚成员函数:

    class Element
    {
       // other stuff
    
       virtual void write_to_stream(std::ostream& stream) const = 0;
    };
    

    重载operator&lt;&lt; 以供Element 调用此函数:

    std::ostream& operator<<(std::ostream& stream, const Element& element)
    {
        element.write_to_stream(stream);  // dynamic dispatch as we call through reference
        return stream;
    }
    

    然后重写派生类中的虚成员函数来控制它们应该如何写:

    template<class T>
    class Vector : public Element
    {
       // other stuff
       virtual void write_to_stream(std::ostream& stream) const
       {
          // whatever you like goes here
       }
    };
    

    【讨论】:

    • 等等,为什么不解引用两次给我一个 Vector 类型的对象?我为 Vector 定义了一个输出运算符,这就是我要使用的运算符。我如何与那个版本进行交互——我必须投射指针吗?
    • *Element::vectors[0] 的静态类型是Element(因为Element::vectors[0]Element*),即使它指向的对象的动态类型确实是Vector&lt;T&gt;(你'没错,我可能不应该说它是“Element 类型的对象”!)在Vector&lt;T&gt; 中重载operator&lt;&lt; 的一种方法是委托给一个虚函数——我将添加一个以我的回答为例。
    • 在原始问题中,取消引用运算符不存在:cout &lt;&lt; Element::vectors[0]; 所以静态类型是 pointer to ...至少从代码中。再说一次,我不使用那个编译器,所以我不习惯错误消息,错误消息实际上可能是在将问题复制到 SO 时,星星掉了。
    • @David Rodriguez:我认为他实际展示的代码就是他所说的“我的 main() 输出可能会告诉你发生了什么——我得到了指针 0x1001000a0”。然后他说“但是,如果我尝试取消引用该指针......”我解释为他将* 添加到代码中(然后从错误消息中的* 中理解)。但我可能误解了,我必须读几遍才能理解这个解释!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-01
    • 2011-12-19
    • 1970-01-01
    • 2011-02-11
    • 2013-02-03
    • 1970-01-01
    相关资源
    最近更新 更多