Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
父子关系所有权的推荐模式 我是C++新手,我想了解引用计数的内存。在下面的代码中,我有两种返回矩形向量的方法 vector<RectangleRef> &rectanglesRef() { return rects_; } vector<RectangleRef> rectangles() { return rects_; } vector&rectanglesRef(){return rects_;} 向量矩形(){返回矩形}_C++_Design Patterns_Shared Ptr - Fatal编程技术网

父子关系所有权的推荐模式 我是C++新手,我想了解引用计数的内存。在下面的代码中,我有两种返回矩形向量的方法 vector<RectangleRef> &rectanglesRef() { return rects_; } vector<RectangleRef> rectangles() { return rects_; } vector&rectanglesRef(){return rects_;} 向量矩形(){返回矩形}

父子关系所有权的推荐模式 我是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

我不确定的是,它们中的任何一个是否在堆栈上为调用方创建了一个新的向量

当一个向量中包含许多ClassB的ClassA想要公开时,推荐的模式是什么?是吗

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_;