如何在C ++中的类之间保留多个引用?

缺口

我有两个类,在示例中添加了Rectangle和Rectangles。目标是制作一个Rectangles对象,其中包含对多个Rectangle对象的引用。

如果我改变r通过r.set_values(4,4)随后关闭粗r.area()改变。但是,如果我称它为rectangles.rects[0].area()12,则不会更改。

据我了解,我正在引用rin 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
神经性

您的代码出了什么问题是您对的定义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::vectorerase同时,也会破坏你的对象。因此,如果以后访问它,将会得到一些肮脏的错误。

std::shared_ptr保留对象的共享所有权。当然,您可以对对象有另一个引用,但是如果销毁指针,也会发生相同的情况。而且,它有一些开销,并且使用起来不那么容易。

std::weak_ptr与配合使用std::shared_ptr,仅此而已。

相反,原始指针只需要确保对象的生存期长于或等于其自身的生存期,这样您就可以始终通过指针访问对象。仅此而已。

最后,这是我常用的经验法则

  • unique_ptrs是唯一拥有权
  • 原始指针意味着给我原始指针的任何人都可以保证该对象的生存期达到或超过我的生存期。
  • shared_ptrs用于共享所有权
  • 当系统想要在使用对象之前检查该对象是否仍然存在时,weak_ptrs适用于该对象。这在我的代码中很少见,因为我发现它更清洁,可以使系统保证通过其子系统的所有内容的生命周期(在这种情况下,我使用原始指针)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C# 如何在类实例之间保留数据?

来自分类Dev

如何在本机反应中管理父子之间的多个引用?

来自分类Dev

如何在C#中的一个类的多个实例之间共享值?

来自分类Dev

如何在多个C#类之间共享属性

来自分类Dev

如何在多个C#类之间共享属性

来自分类Dev

如何在C ++中通过引用分配类实例?

来自分类Dev

如何在 javascript 中由类创建的对象和扩展类之间进行引用?

来自分类Dev

如何在Dockerfile中的多个CMD语句之间保留R工作区?

来自分类Dev

如何在C ++ 14中保留左值引用的同时衰减右值引用类型?

来自分类Dev

如何在Swift中引用类?

来自分类Dev

如何在烧瓶中引用多个模型?

来自分类Dev

如何在mysql中引用多个列?

来自分类Dev

如何在 if 条件中引用多个变量

来自分类Dev

如何在C代码中引用汉字

来自分类Dev

如何在C中的函数调用之间保留联合成员的值?

来自分类Dev

如何在java中的类之间链接

来自分类Dev

如何在C ++中制作可比类

来自分类Dev

如何在C ++中实现静态类?

来自分类Dev

如何在C#中调用类

来自分类Dev

如何在C ++中制作可比类

来自分类Dev

如何在C ++类中输入变量?

来自分类Dev

如何在C ++类中调试变量?

来自分类Dev

如何在C ++中遍历多个函数?

来自分类Dev

如何在C ++中启动多个线程

来自分类Dev

C ++如何在单个定义中的多个声明符中定义const引用?

来自分类Dev

如何在多个类中实现dbContext

来自分类Dev

如何在CodeIgniter中扩展多个类?

来自分类Dev

如何在vueJs中绑定多个类

来自分类Dev

如何在awk中的字段之间保留原始空格?