簡體   English   中英

為什么我不能擁有指向與成員變量具有相同指針類型的對象的指針?

[英]Why can't I have pointers to objects, which have the same type of pointer as a member variables?

我的發音方式聽起來有些怪異,但這僅僅是因為我不知道該如何表達。 我正在嘗試實現A *,之前已經實現了,但是在追溯路徑時遇到了一個問題,因此我決定進行一次小型測試。 問題是這樣的:

我有一堂課,看起來像這樣:

class Number {
public:
    int xPos;
    int yPos;

    Number *prevNum;
    Number(int x, int y) {
        xPos = x;
        yPos = y;
    }
};

在主要功能中,我這樣做

int main() {
    Number n(2, 2);
    Number *current = &n;
    vector<Number> nums;
    nums.push_back(*current);
    for (unsigned i = 0; i < 15; i++) {
        Number n(current->xPos + 1, current->yPos);
        n.prevNum = current;
        nums.push_back(n);
        current = &n;
        cout << current->xPos + 1 << " ";
    }
    for (unsigned i = 0; i < nums.size(); i++) {
        if (nums.at(i).prevNum) {
            cout << nums.at(i).prevNum->xPos << " ";
        }
    }
    return 0;
}

由於某種原因,它返回以下內容:

4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 555437610 2 17 17 17 17 17 17 17 17 17 17 17 17 17 17

555437610每次都不同,因此我認為指針可能有錯誤。 我不能無限嵌套成員函數* prevNum嗎? 我不確定如何描述它。

你的問題是

current = &n;

在這里,您要獲取循環局部變量的地址。 在迭代結束時,該變量被銷毀,這意味着您有一個指向不再存在的對象的指針。 取消引用該指針是未定義的行為。

如果要保留定義的行為,那么您應該做的就是在向量中存儲一個指向對象的指針。 調用push_back之后,該指針可能/將失效,但是由於您在此之前使用了指針,所以可以。 你應該沒事的

current = &nums.back();

您還將在存儲先前的指針時遇到問題。 如果從矢量捕獲元素,則如果矢量重新分配空間,則將剩下一個懸空指針。 我認為您將需要某種shared_ptr設置才能使其正常工作。

你有:

for (unsigned i = 0; i < 15; i++) {
    Number n(current->xPos + 1, current->yPos);
    n.prevNum = current;
    nums.push_back(n);
    current = &n;
    cout << current->xPos + 1 << " ";
}

在那里, n是一個局部變量,該變量在循環結束時被銷毀。 您正在存儲一個指向局部變量的指針,並在以后使用它。

您的程序具有未定義的行為。


我不清楚,為什么需要prevNum成員變量。 您可以完全擺脫它。

#include <iostream>
#include <vector>

using namespace std;

class Number {
public:
    int xPos;
    int yPos;

    Number(int x, int y) {
        xPos = x;
        yPos = y;
    }
};

int main() {
   Number n(2, 2);
   vector<Number> nums;
   nums.push_back(n);
   for (unsigned i = 0; i < 15; i++) {
      Number n(2+i+1, 2);
      nums.push_back(n);
      cout << 2 + i+1 << " ";
   }
   cout << endl;
   for (unsigned i = 0; i < nums.size(); i++) {
      cout << nums.at(i).xPos << " ";
   }
   cout << endl;
   return 0;
}

n的范圍僅是for循環。 所以current = &n; current設置為指向將很快超出范圍的對象。

nums.push_back(n); 復制n到向量中,它是&nums.back()您應該分配給current

實際上,您的程序可以簡化如下:

struct Number { // Now a proper aggregate
    int xPos;
    int yPos;

    Number *prevNum;
};

vector<Number> nums {{1, 2, nullptr}};
nums.reserve(16);
for (unsigned i = 0; i < 15; ++i) {
    Number& back = nums.back();
    nums.emplace_back({back.xPos + 1, back.yPos + 1, &back});
    cout << nums.back().xPos + 1 << " ";
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM