更改指针指向的内容

Changing what a pointer points to?

本文关键字:指针      更新时间:2023-10-16

我对编程很陌生,并且接近这个程序的末尾,但无法完全完成最后一个细节,我一直坚持下去。我正在尝试切换指针 *sp 指向的形状,在我看来,我正在做的事情应该有效,因为矩形和圆形都是形状;但是,当我编译时,只有颜色的值发生了变化。打印圆形区域而不是矩形区域,周长打印 0。任何帮助将不胜感激!

#include <iostream>
#include <string>
using namespace std;
double const pi = 3.1519;
class shape {
    public:
        shape() {};
        shape(string);
        virtual double getCircumference() {
            return 0;
        };
        virtual double getPerimeter() {
            return 0;
        };
        virtual double getArea() {
            return 0;
        };
        string getColor();

    protected:
        string color;
};
string shape::getColor() {
    return color;
}
class circle : public shape {
public:
    circle(double r, string c) {
        radius = r;
        color = c;
    };
    double getArea();
    double getCircumference();

private:
    double radius;

};
double circle::getCircumference() {
    return pi * radius * 2;
}
double circle::getArea() {
    return pi * radius * radius;
}
class rectangle:public shape {
public:
    rectangle(double w, double l, string c) {
        width = w;
        length = l;
        color = c;
    };
    double getArea();
    double getPerimeter();
private:
    double length;
    double width;
};
double rectangle::getPerimeter() {
    return width * 2 + length * 2;
}
double rectangle::getArea() {
    return length * width;
}
void change(shape *sp, shape *sp1) {
    *sp = *sp1;
}
int main() {
    circle mary(3.2, "Green");
    shape *sp = new circle(4.5, "Yellow");
    cout << "Circle #1 is " << mary.getColor() << endl;
    cout << "Circle #1 has an area of " << mary.getArea() << endl;
    cout << "Circle #1 has a circumference of " << mary.getCircumference() << endl << endl;
    cout << "Circle #2 is " << sp->getColor() << endl;
    cout << "Circle #2 has an area of " << sp->getArea() << endl;
    cout << "Circle #2 has a circumference of " << sp->getCircumference() << endl << endl;
    shape *sp1 = new rectangle(1.0, 2.1, "Red");
    change(sp, sp1);
    cout << "Rectangle #1 is " << sp->getColor() << endl;
    cout << "Rectangle #1 has an area of " << sp->getArea() << endl;
    cout << "Rectangle #1 has a perimeter of " << sp->getPerimeter() <<endl<< endl;
}
重要的是要

记住使用指针的各种不同方式的含义。在程序中,sp是指指针本身,即告诉计算机在何处查找对象的内存位置。*sp中的星号是"取消引用"运算符;它需要一个指针,并给你它所指向的东西。

考虑到这一点,你的台词*sp = *sp1;说,"把sp指向的东西,设置为等于sp1指向的东西。换句话说,您正在更改 sp 指向的对象的值,而不是sp本身的值。要sp指向 sp1 指向的对象,您需要不带星号sp = sp1;

要记住的另一件事是,默认情况下C++按值传递函数参数:调用函数时,将复制参数,并且函数对副本进行操作。这意味着原始参数本身不能被这样工作的函数更改。向参数声明添加 & 符号,如 void change(shape *&sp, shape *sp1) 会导致第一个参数通过引用传递:函数操作的对象与调用代码传入的对象相同。这允许函数更改作为参数传递的对象,并在函数返回后保留这些更改。

对不起,回答冗长:我本可以给你几行你想要的,但我想你可能会喜欢解释为什么事情会这样工作的原因。

如果要尝试更改指针的地址,则必须通过引用传递指针。试试这个:

void change(shape *&sp, shape *&sp1)
指针

是按值传递的,即使它是指针。

这意味着您实际上是按值传递地址,因此参数是原始参数的副本。

一想

void sum(int a, int b, int result);
void foo() {
  int result;
  sum(5,10,result);
}

虽然您希望能够将结果存储到传递给sum参数的变量中,但您将无法做到这一点,因为result是按值传递并因此被复制的。对方法内部result所做的每次修改都将是该方法的本地修改。

这是完全相同的事情,指针只不过是一个地址,如果你按值传递它,那么就会传递地址的副本,但对局部变量的每次修改都只是局部的。

这就是为什么如果您希望能够像修改其他变量一样修改它们的值,则必须使用引用,因此您将拥有

void sum(int a, int b, int& result);
void change(shape*& shape1, shape*& shape2);

在后台,这将把地址传递给存储地址的变量(一种shape**(,这样函数就能够知道原始参数的位置并直接修改它。