我有两个类,在示例中添加了矩形和矩形。目标是使一个矩形对象保存对多个矩形对象的引用。
如果我把r
改为r.set_values(4,4)
,那么粗r.area()
就变了。但是,如果我调用rectangles.rects[0].area()
,它仍然是12,因此不会更改。
据我所知,我在rectangles
中引用了rectangles
,但这似乎是错误的。
如何做到这一点?
代码是可用的这里
#include <iostream>
using namespace std;
class Rectangle {
int width, height;
public:
void set_values (int,int);
int area() {return width*height;}
};
void Rectangle::set_values (int x, int y) {
width = x;
height = y;
}
class Rectangles {
public:
Rectangles(int n);
void addRectangle(Rectangle* r);
Rectangle* rects;
int nRects;
};
Rectangles::Rectangles(int n) {
rects = new Rectangle[n];
nRects = 0;
}
void Rectangles::addRectangle(Rectangle* r) {
rects[nRects] = *r;
nRects++;
}
int main() {
Rectangle r;
Rectangles rectangles(5);
r.set_values(4,3);
rectangles.addRectangle(&r);
cout<<"r.area() before change:"<<r.area()<<endl;
cout<<"rectangles.rects[0].area() before change:"<<rectangles.rects[0].area()<<endl;
r.set_values(4,4);
cout<<"r.area() after change:"<<r.area()<<endl;
cout<<"rectangles.rects[0].area() after change:"<<rectangles.rects[0].area()<<endl;
return 0;
}
输出:
r.area() before change:12
rectangles.rects[0].area() before change:12
r.area() after change:16
rectangles.rects[0].area() after change:12
发布于 2014-09-03 09:16:53
代码的问题在于您对Rectangles
的定义。它存储指向Rectangle
的指针(或数组)。这里您想要的不是一个Rectangle
的数组,而是一个对Rectangle
的引用数组。在这里,引用应该是指针,因此您需要相应地更改它:
class Rectangles {
public:
Rectangles(int n);
void addRectangle(Rectangle* r);
// Rectangle* rects;
// What you really want :
Rectangle** rects;
int nRects;
};
但是,您还需要更改实现:
Rectangles::Rectangles(int n) {
rects = new Rectangle*[n]; // Array of pointers
nRects = 0;
}
void Rectangles::addRectangle(Rectangle* r) {
rects[nRects] = r; // r is a pointer : just store it, no dereferencing
nRects++;
}
但是,这是一个错误的设计:您不应该使用其中的任何一个:指向指针(或指针的“原始数组”)的指针、new
和一个类,其唯一目的是存储一个事物数组。这是因为您已经有了更好的工具:智能指针(尽管这里也不需要它们)、数组和动态数组(或向量)。
所以,如果我是你,我会这样重写你的代码:
#include <iostream>
#include <vector>
class Rectangle {
public:
void setSize(int w, int h);
int area();
private:
int width, height;
};
void Rectangle::setSize(int w, int h) {
width = w;
height = h;
}
int Rectangle::area() {
return width * height;
}
int main() {
Rectangle r;
std::vector<Rectangle*> rectangles;
r.setSize(4, 3);
rectangles.push_back(&r);
std::cout << "r.area() before change : " << r.area() << std::endl
<< "rectangles[0]->area() before change : "
<< rectangles[0]->area() << std::endl;
r.setSize(4, 4);
std::cout << "r.area() after change : " << r.area() << std::endl
<< "rectangles.rects[0]->area() after change : "
<< rectangles[0]->area() << std::endl;
return 0;
}
编辑:
您可能想知道为什么我使用原始指针而不是智能指针(因为我告诉过您要避免指针指针)。这很简单:没有一个智能指针适合这个问题。让我们看看为什么。
std::unique_ptr
保持对象的唯一所有权。如果你想要另一个参考呢?此外,如果您曾经通过std::vector
的erase
销毁这个智能指针,它也会破坏您的对象。因此,如果您事后访问它,您将得到一些肮脏的错误。
std::shared_ptr
保持对象的共享所有权。当然,您可以有另一个对对象的引用,但如果销毁指针,也会发生同样的情况。另外,它也有一些开销,并且不太容易正确使用。
std::weak_ptr
和std::shared_ptr
一起工作,没什么可说的。
相反,原始指针只需要确保对象的生存期更长或等于它自己的生命周期,这样就可以始终通过指针访问对象。仅此而已。
最后,这是拇指的一般规则 (我使用的):
https://stackoverflow.com/questions/25640017
复制相似问题