2016-02-12 81 views
0

我对编程非常陌生,接近这个程序的结尾,但不能完全完成我一直坚持的最后一个细节。我试图切换指向* 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; 

} 
+1

你忘了在'void change(shape * sp,shape * sp1)'中通过引用传递。应该是'void change(shape *&sp,shape *&sp1)' – NathanOliver

+0

Thanks NathanOliver! – Reggie78

+0

作为一个函数,我不确定'change'的含义(除了帮助你学会通过引用来改变?),当你可以只是'sp = new rectangle ...'而不是? (无论哪种方式,你都不会通过删除旧对象来泄漏内存)。 – crashmstr

回答

1

如果你想改变指针的地址,你必须通过引用传递指针。试试这个:

void change(shape *&sp, shape *&sp1) 
+0

非常感谢!这就是诀窍! – Reggie78

0

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

这意味着你实际上是按值传递的地址,这样的说法是原始参数的副本。

想想

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**),所以函数能够知道原始参数的位置并直接修改它。

1

重要的是要保持什么是使用指针的各种不同方式的意思是非常重要的。在你的程序中,sp引用指针本身 - 也就是说,一个内存位置告诉计算机在哪里找到一个对象。 *sp中的星号是'取消引用'操作符;它需要一个指针并给你指向的东西。

考虑到这一点,你行*sp = *sp1;是说,“拿着这个sp指向的东西,并将它设置为等于sp1指向。东西”换句话说,要更改的值sp指向的对象的值,而不是sp本身的值。来点sp在指向的对象sp1,你需要sp = sp1;没有星号。

其他的事情要记住的是,C++默认按值传递函数参数:当函数被调用,参数复制,以及功能上的复制操作。这意味着原始参数本身不能被一个像这样工作的函数改变。添加一个符号到参数声明,像void change(shape *&sp, shape *sp1)引起的第一个参数通过引用传递:对象函数操作上是一个由调用代码传递的同一个对象。这允许该函数更改作为参数传递的对象,以及在函数返回后保留这些更改。

对不起,很长的回答:我可以给你几行,做你想做的事,但我想你可能会喜欢解释为什么事情按照他们的方式工作。