初始化静态指针结果为<undefined value =“”>

时间:2016-02-11 22:49:17

标签: pointers c++-cli

我在托管C ++中使用Pointers只是一个初学者问题让我很头疼。我正在创建一个元素列表,指针应该显示该列表的当前元素。

问题是,当我将第一个元素分配给此列表时,我想用我的指针(“varPointer =&amp; firstElem”)引用此列表的开头。但在那之后,指针根本没有任何价值。

以下是我的代码的简化版本:

ref class ElementClass
{
public:
    value struct Element
    {
        //some items here ...;
        Element *Next, *Previous;
    };
    ...
}

ref class Queue
{
 public:
      static Element* queue;

      static void AddElem(Element* elem)    {
        //Check, if queue is empty
        if (queue == nullptr) {
            queue = elem;
            queue->Previous = nullptr;
         }
         else {             
            queue->Next = elem;
            elem->Previous = queue;
            queue = elem;           
         }
    }
}

程序不会抛出任何错误,在下一次迭代中,列表似乎仍为空。 即使我使用“static Element * queue = 0”或队列指针始终具有的内容显式初始化队列。无法使用“Element”实例进行初始化(“类型'interior_ptr'的值不能用于初始化'Element *'类型的实体。)为此,我添加了:

...
public:
    static Element^ tmpElem = gcnew Element();
    static Element* queue = &tmpElem;
...

程序从不使用else语句。 我感谢任何帮助。提前谢谢大家。

(我对编程很熟悉,但顺便说一句,我是C ++的新手。)

1 个答案:

答案 0 :(得分:0)

好的。这是教育性的。

所以,如果你使用传统的非托管指针

Element *Next = nullptr, *Previous = nullptr;

然后使用按值传递

static void AddElem(ElementClass::Element elem) {
    //Check, if queue is empty
    if (queue == nullptr) {
        queue = &elem;
        queue->Previous = nullptr;
    }
    else {
        queue->Next = &elem;
        elem.Previous = queue;
        queue = &elem;
    }
}

Kablooey! elem被复制在其中并且将超出范围并在返回的路上被销毁或被标记为销毁并且在不久的将来某个时刻由垃圾收集器死亡。我不确定这个,但是在你完成之前它很可能会被破坏。这留下了一堆指向无效内存的指针。如果程序没有崩溃,那不是因为它有效。这是因为你运气不好而且看起来很有效。

如果你一直回到C风格:

Element *Next = nullptr, *Previous = nullptr;

然后传入一个非托管指针

static void AddElem(ElementClass::Element * elem) {
    //Check, if queue is empty
    if (queue == nullptr) {
        queue = elem;
        queue->Previous = nullptr;
    }
    else {
        queue->Next = elem;
        elem->Previous = queue;
        queue = elem;
    }
}

它可以工作,但您必须手动完成所有内存管理。没有垃圾收集。

如果使用托管指针,则会获得托管内存。好东西。

Element ^Next = nullptr, ^Previous = nullptr;

然后

static void AddElem(ElementClass::Element elem) {
    //Check, if queue is empty
    if (queue == nullptr) {
        queue = elem;
        queue->Previous = nullptr;
    }
    else {
        queue->Next = elem;
        elem.Previous = queue;
        queue = elem;
    }
}

这个存储,据我所知,它管理elem的副本,保持副本存活。原来的元素不受影响。它不知道它是否被链接,因为它不是。副本已关联。这可能就是你所需要的。看作Element是值类型,这应该是你想要的全部。

否则请选择端到端托管指针。

static void AddElem(ElementClass::Element ^ elem) {
    //Check, if queue is empty
    if (queue == nullptr) {
        queue = elem;
        queue->Previous = nullptr;
    }
    else {
        queue->Next = elem;
        elem->Previous = queue;
        queue = elem;
    }
}

注意我没有改变任何链表逻辑。这很好。