父子关系所有权的推荐模式 我是C++新手,我想了解引用计数的内存。在下面的代码中,我有两种返回矩形向量的方法 vector<RectangleRef> &rectanglesRef() { return rects_; } vector<RectangleRef> rectangles() { return rects_; } vector&rectanglesRef(){return rects_;} 向量矩形(){返回矩形}
我不确定的是,它们中的任何一个是否在堆栈上为调用方创建了一个新的向量 当一个向量中包含许多ClassB的ClassA想要公开时,推荐的模式是什么?是吗父子关系所有权的推荐模式 我是C++新手,我想了解引用计数的内存。在下面的代码中,我有两种返回矩形向量的方法 vector<RectangleRef> &rectanglesRef() { return rects_; } vector<RectangleRef> rectangles() { return rects_; } vector&rectanglesRef(){return rects_;} 向量矩形(){返回矩形},c++,design-patterns,shared-ptr,C++,Design Patterns,Shared Ptr,我不确定的是,它们中的任何一个是否在堆栈上为调用方创建了一个新的向量 当一个向量中包含许多ClassB的ClassA想要公开时,推荐的模式是什么?是吗 void addRectangle(RectangleRef r) { rects_.push_back(r); } void removeRectangle(RectangleRef r); vector<RectangleRef> rectangles() { return rects_; } void addRectangle
void addRectangle(RectangleRef r) { rects_.push_back(r); }
void removeRectangle(RectangleRef r);
vector<RectangleRef> rectangles() { return rects_; }
void addRectangle(rectangler){rects_u.push_uback(r)}
空隙清除器角度(矩形参考);
向量矩形(){返回矩形}
或者您只是让调用者访问内部结构,并允许他们随意添加/删除内容
如果矩形类要保留一个指向它所属的测试类的返回指针,则使用
typedef std::weak_ptr<Test> TestWeakRef;
...
TestWeakRef test_;
typedef std::weak_ptr TestWeakRef;
...
TestWeakRef测试;
正确的成语
谢谢你的帮助
守则:
#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;
}
#包括
#包括
#包括
使用名称空间std;
类点{
公众:
点(){
x=0.0;
y=0.0;
}
点(双x,双y){
x_uux=x;
y=y;
}
双x()常量{return x_;}
双y()常量{return y_;}
void setX(双x){x_ux=x;}
void setY(双y){y_uu=y;}
空隙偏移(双dx,双dy){
setX(x()+dx);
setY(y()+dy);
}
布尔运算符==(点常量和点){
返回x()==point.x()&&y()==point.y();
}
void运算符=(点常量和点){
setX(point.x());
setY(point.y());
}
私人:
双x;
双y;
};
班级人数{
公众:
大小(){
宽度=0.0;
高度=0.0;
}
尺寸(双倍宽度,双倍高度){
宽度=宽度;
高度=高度;
}
双宽度()常量{返回宽度}
双高度()常量{返回高度}
双面积()常数{返回宽度()*高度();}
void setWidth(双倍宽度){width\uu=width;}
void setHeight(双倍高度){height_u=height;}
私人:
双倍宽度,高度;
};
类矩形{
公众:
矩形(){
原点=点();
大小=大小();
}
矩形(双x、双y、双宽、双高){
原点=点(x,y);
尺寸=尺寸(宽度、高度);
}
点原点()常量{返回原点}
Size Size()常量{返回大小}
私人:
点原点;
大小;
};
typedef标准::共享矩形参考;
typedef std::弱矩形weakref;
课堂测试{
私人:
向量矩形;
公众:
测试(){
矩形=向量();
对于(int i=0;i<100;i++){
矩形参考ptr=使_共享(i*1.0,0.0,1.0,1.0);
矩形推回(ptr);
}
}
向量和矩形ref(){返回矩形}
向量矩形(){返回矩形}
};
int main(int argc,const char*argv[]{
向量r;
载体r1;
如果(真){
测试t=测试();
r=t.矩形();
r1=t.矩形REF();
如果(r1==r){cout欢迎来到Stack Overflow!您的几个问题集合有点混乱,但我会尽力解决
我不确定的是,它们中的任何一个是否在堆栈上为调用方创建了一个新的向量
这将创建一个完整的新向量
vector<RectangleRef> rectangles() { return rects_; }
vector rectangles(){返回矩形}
这避免了复制
vector<RectangleRef> &rectanglesRef() { return rects_; }
vector&rectanglesRef(){return rects_;}
当你有一个向量中包含许多ClassB的ClassA,你希望能够公开它时,推荐的模式是什么?你是这样做的……还是你只是让调用者访问内部结构,允许他们随意添加/删除东西
常见的范例是像您一样提供访问器函数。我建议这样做
如果矩形类要保留一个指向它所属测试类的返回指针,那么使用std::weak_ptr
是否正确
是的,这是一个很好的方法。Drew Dorman很好地回答了前几个问题。我只是补充了一些东西
首先,如果您确实需要共享所有权语义,您应该只使用shared\u ptr
。引用计数有开销,如果您没有正确地分解循环依赖项,它将导致内存泄漏,因此除非您确实需要,否则不应该这样做
在这段代码中,没有真正的理由需要存储一个向量
,而不是一个简单的向量
。后者还有更好的数据局部性的好处,这对缓存很重要
第二,这个
typedef std::weak_ptr<Test> TestWeakRef;
// ...
TestWeakRef test_;
如果存储在测试中的矩形
的生存期可以超过测试
的生存期(只有在您没有独占所有权的情况下才会发生这种情况(例如,存储共享的ptr
给他们),这通常是不必要的),您的Test
析构函数可能必须穿过它存储的矩形,清除指针以防止指针悬空。但典型的情况是,存储在Test
对象中的内容将在对象被销毁时消失,在这种情况下,这是不必要的。因为向量中的内容是什么实际上是shared\u ptr
s,返回常量引用(或按值)不会阻止对底层矩形的修改。@t.C.捕捉得好!我完全错过了。
Test * test_;