我做了一个小例子:
#include <iostream>
#include <conio.h>
using namespace std;
// skipped getters and setters and bounds checking for brevity
struct Vertex {
int x,y;
Vertex() {
}
Vertex(int x, int y) {
this->x = x;
this->y = y;
}
};
struct Polygon {
Vertex *vertexlist;
Polygon() {
}
Polygon(Vertex *v) {
vertexlist = new Vertex[4]; //hard coded 4 vertices for example brevity
for(int i=0;i<4;i++) {
vertexlist[i] = v[i];
}
}
Vertex& getVertex(int index) const {
return this->vertexlist[index];
}
};
struct PolyList {
Polygon *polylist;
int lastpoly;
PolyList() {
polylist = new Polygon[10]; //hard coded 10 for example brevity
lastpoly = 0;
}
void add(const Polygon& p) {
polylist[lastpoly++] = p;
}
};
ostream& operator<<(ostream& o, Vertex& v) {
return o << "(" << v.x << ", " << v.y << ")";
}
ostream& operator<<(ostream& o, const Polygon& p) {
for(int i=0;i<4;i++) {
o << p.getVertex(i) << ", ";
}
return o;
}
ostream& operator<<(ostream& o, PolyList& pl) {
for(int i=0;i<pl.lastpoly;i++) {
o << pl.polylist[i] << endl;
}
return o;
}
int someFunc() {
Vertex *vl = new Vertex[4];
PolyList pl;
vl[0] = Vertex(1,2);
vl[1] = Vertex(3,4);
vl[2] = Vertex(5,6);
vl[3] = Vertex(7,8);
pl.add(Polygon(vl)); // this Polygon goes out of scope after this line
cout << pl << endl;
}
int main() {
someFunc();
}
(所以tl; dr,Polygon
是4x Vertex
的列表,PolyList
是Polygon
:s的列表。Polygon
:s通过实例化临时add()
)
PolyList
为Polygon
现在,这会泄漏内存,因为Polygon
中的顶点永远不会被释放。但是,如果我添加一个析构函数:
Polygon :: ~Polygon(){delete [] vertices}
然后
cout&lt;&lt; pl&lt;&lt; ENDL;
因为Polygon
超出了范围而析构函数释放了顶点,所以不起作用。
我可以让PolyList
析构函数调用Polygon->free()
函数。或者,我可以让Polygon::Polygon(Vertex *v)
深度复制v中的所有顶点。然后PolyList::PolyList(Polygon &p)
可以深层复制p。
我也可以制作一个PolyList::createPolygon(int x1, int y1, int x2, int y2...)
,但面对OO会飞。
在C ++中处理这种情况的正确方法是什么?别介意我的实际例子,内存泄漏不会成为问题,我原则上在谈论。如果我创建一个分层对象树,我想复制指针,而不是深层复制对象。
编辑:我正在尝试深层学习C ++,所以这不是关于使用vector&lt;&gt;或另一种“罐装解决方案”;这不是我在这里所说的,虽然我确信如果上面的例子是我遇到的实际问题,这是一个很好的解决方案。上面的例子只是我能想到解释我的问题的最简单的例子。
答案 0 :(得分:1)
您可以使用smart pointers和STL containers(主要是std::vector
,如PaulMcKenzie所建议的那样)。
他们会帮助很多。
#include <iostream>
#include <conio.h>
#include <vector>
using namespace std;
// skipped getters and setters and bounds checking for brevity
struct Vertex {
int x, y;
Vertex() {
}
Vertex(int x, int y) {
this->x = x;
this->y = y;
}
};
typedef vector<Vertex> vertex_list_t;
struct Polygon {
vertex_list_t vertexlist;
Polygon() {
}
Polygon(vertex_list_t v) {
//hard coded 4 vertices for example brevity
for (int i = 0; i<4; i++) {
vertexlist.push_back(Vertex(i, i));
}
}
Vertex getVertex(int index) const {
return vertexlist[index];
}
};
typedef vector<Polygon> polygon_list_t;
ostream& operator<<(ostream& o, Vertex& v) {
return o << "(" << v.x << ", " << v.y << ")";
}
ostream& operator<<(ostream& o, const Polygon& p) {
for (auto v: p.vertexlist) {
o << v << ", ";
}
return o;
}
ostream& operator<<(ostream& o, polygon_list_t& pl) {
for (auto &p : pl) {
o << p << endl;
}
return o;
}
int someFunc() {
vertex_list_t vl = {
Vertex(1, 2),
Vertex(3, 4),
Vertex(5, 6),
Vertex(7, 8)
};
polygon_list_t pl;
pl.push_back(Polygon(vl)); // this Polygon goes out of scope after this line
cout << pl << endl;
return 0;
}
int main() {
someFunc();
}
在第
行pl.add(Polygon(vl)); // this Polygon goes out of scope after this line
您将多边形作为临时对象传递:
$ 12.2 / 3-“作为评估全表达式(1.9)的最后一步,临时对象被销毁(词法)包含创建它们的点。即使该评估以抛出异常结束,也是如此。 “
通过以下方式更改该行:
Polygon p1(vl);
pl.add(p1); // this Polygon NOT goes out of scope after this line
答案 1 :(得分:0)
您可以使用shared_ptrs作为解决方案。即。
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <memory>
#include <list>
#include <vector>
using namespace std;
struct Vertex
{
int x,y;
Vertex() : x(0), y(0)
{
}
Vertex(int _x, int _y)
{
x = _x;
y = _y;
}
};
struct Polygon
{
vector<Vertex> vertexes;
Polygon()
{
}
Polygon(Vertex *v)
{
const int ELEMS_COUNT = 4;
vertexes.reserve(ELEMS_COUNT);
vertexes.insert(vertexes.end(), v, v + ELEMS_COUNT);
}
Vertex getVertex(int index) const
{
return vertexes[index];
}
};
typedef shared_ptr<Polygon> PolygonPtr;
struct PolyList
{
std::list<PolygonPtr> polylist;
void add(PolygonPtr p)
{
polylist.push_back(p);
}
};
ostream& operator<<(ostream& o, const Vertex& v) {
return o << "(" << v.x << ", " << v.y << ")";
}
ostream& operator<<(ostream& o, const Polygon& p) {
for (auto& p : p.vertexes)
{
o << p << ", ";
}
return o;
}
ostream& operator<<(ostream& o, PolyList& pl) {
for(auto& p : pl.polylist)
{
o << *p << endl;
}
return o;
}
int someFunc() {
Vertex vl[] = {Vertex(1, 2), Vertex(3, 4), Vertex(5, 6), Vertex(7, 8)};
PolyList pl;
pl.add(PolygonPtr(new Polygon(vl)));
cout << pl << endl;
return 0;
}
int main()
{
someFunc();
return 0;
}