为什么我不能指向对象,指针与成员变量具有相同类型的指针?

时间:2016-12-30 20:37:20

标签: c++ pointers

我说的方式听起来有点奇怪,但那只是因为我不知道我怎么能说出来。我正在尝试实现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吗?我不完全确定如何形容它。

3 个答案:

答案 0 :(得分:3)

你的问题在于

current = &n;

在这里,您将获取循环局部变量的地址。在迭代结束时,变量被销毁,这意味着您有一个指向不再存在的对象的指针。取消引用该指针是未定义的行为。

如果要保持定义的行为,那么您应该做的是在向量中存储指向对象的指针。在调用push_back之后,该指针可能会/将被无效,但由于您在此之前使用它,这将是正常的。

你应该没问题
current = &nums.back();

您在存储前一个指针时也会遇到问题。如果从向量中捕获元素,如果向量重新分配空间,那么您将留下一个悬空指针。我认为您需要某种shared_ptr设置才能使其正常运行。

答案 1 :(得分:2)

你有:

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;
}

答案 2 :(得分:1)

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 << " ";
}