gpt4 book ai didi

c++ - 父子关系所有权的推荐模式

转载 作者:行者123 更新时间:2023-11-30 04:03:45 24 4
gpt4 key购买 nike

我是 C++ 的新手,正在尝试了解引用计数内存。在下面的代码中,我有两种返回矩形 vector 的方法

vector<RectangleRef> &rectanglesRef() { return rects_; }
vector<RectangleRef> rectangles() { return rects_; }

我不确定的是他们中的任何一个是否在堆栈上为调用者创建了一个新的 vector ?

当您的 ClassA 在您希望能够公开的 vector 中包含许多 ClassB 时,推荐的模式是什么?你有吗

void addRectangle(RectangleRef r) { rects_.push_back(r); }
void removeRectangle(RectangleRef r);
vector<RectangleRef> rectangles() { return rects_; }

或者您只是让调用者访问内部结构并允许他们随意添加/删除内容?

如果 Rectangle 类要保留指向它所属的 Test 类的后向指针,则正在使用

typedef std::weak_ptr<Test> TestWeakRef;
...
TestWeakRef test_;

正确的成语?

感谢您的帮助。

代码:

#include <iostream>
#include <limits>
#include <vector>

using namespace std;

class Point {
public:
Point() {
x_ = 0.0;
y_ = 0.0;
}

Point(double x, double y) {
x_ = x;
y_ = y;
}

double x() const { return x_; }
double y() const { return y_; }

void setX(double x) { x_ = x; }
void setY(double y) { y_ = y; }

void offset(double dx, double dy) {
setX(x() + dx);
setY(y() + dy);
}

bool operator == (Point const &point) {
return x() == point.x() && y() == point.y();
}

void operator = (Point const &point) {
setX(point.x());
setY(point.y());
}

private:
double x_;
double y_;
};


class Size {
public:
Size() {
width_ = 0.0;
height_ = 0.0;
}

Size(double width, double height) {
width_ = width;
height_ = height;
}

double width() const { return width_; }
double height() const { return height_; }
double area() const { return width() * height(); }

void setWidth(double width) { width_ = width; }
void setHeight(double height) { height_ = height; }

private:
double width_, height_;
};

class Rectangle {
public:
Rectangle() {
origin_ = Point();
size_ = Size();
}

Rectangle(double x, double y, double width, double height) {
origin_ = Point(x, y);
size_ = Size(width, height);
}

Point origin() const { return origin_; }
Size size() const { return size_; }

private:
Point origin_;
Size size_;
};

typedef std::shared_ptr<Rectangle> RectangleRef;
typedef std::weak_ptr<Rectangle> RectangleWeakRef;

class Test {
private:
vector<RectangleRef> rects_;

public:
Test() {
rects_ = vector<RectangleRef>();

for (int i = 0; i < 100; i++) {
RectangleRef ptr = make_shared<Rectangle>(i*1.0, 0.0, 1.0, 1.0);
rects_.push_back(ptr);
}
}

vector<RectangleRef> &rectanglesRef() { return rects_; }
vector<RectangleRef> rectangles() { return rects_; }
};

int main(int argc, const char * argv[]) {

vector<RectangleRef> r;
vector<RectangleRef> r1;

if (true) {
Test t = Test();

r = t.rectangles();
r1 = t.rectanglesRef();

if (r1 == r) { cout << "they match\n"; }
}

// insert code here...
//std::cout << r->origin().x() << "\n";
return 0;
}

最佳答案

Drew Dormann 很好地回答了前几个问题。我只是添加一些内容。

首先,你真的应该只使用 shared_ptr如果您确实需要共享所有权语义。引用计数有开销,如果你没有正确地分解循环依赖,它会导致内存泄漏,所以你不应该这样做,除非你确实需要它。

在这段代码中,没有真正的理由需要存储 vector<RectangleRef>而不是简单的 vector<Rectangle> .后者还具有更好的数据局部性优势,这对于缓存很重要。

二、这个

typedef std::weak_ptr<Test> TestWeakRef;
// ...
TestWeakRef test_;

通常不是一个好主意,因为它限制了 Test 的生命周期管理策略。 .也就是说,因为 weak_ptr 只能引用一个生命周期由shared_ptr管理的对象,你只是让它不可能做像 Test t; 这样的事情或 unique_ptr<Test> t; .除非你有非常非常好的理由,否则不要这样做。

如果你想要反向指针,只需使用一个简单的非拥有原始指针,无论 Test 是否存在,它都可以工作。对象在堆栈上或由 unique_ptr 管理或 shared_ptr或其他一些自定义智能指针:

Test * test_;

如果 Rectangle 的生命周期s 存储在 Test 中可以超过 Test 的生命周期(这只有在您不拥有它们的独占所有权时才会发生(例如,将 shared_ptr 存储给它们),这通常是不必要的),您的 Test析构函数可能必须经过 Rectangle它存储并清除指针以防止悬空指针。但典型情况是用 Test 存储的内容当对象被销毁时对象将消失,在这种情况下这是不必要的。

关于c++ - 父子关系所有权的推荐模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24215850/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com