简体   繁体   English

我需要一些C ++结构建议

[英]I need some C++ structure advice

I have one instance of Class A. It has two members, Object A and Object B. I need to create ONE instance of Object A (which is quite a large object), and TWO instances of object B, and then give both instances of object B access to that object A. They don't ever need to change object A, they just need to access its info. 我有一个类A的实例。它有两个成员,对象A和对象B。我需要创建一个对象A(这是一个很大的对象)的实例,以及两个对象B的实例,然后给它们两个实例对象B访问该对象A。他们不需要更改对象A,只需要访问其信息即可。

Right now, I got it all to work by creating Object A as a pointer, passing it into both instances of Object B, who have their own pointer that then points to the same place in memory as Object A's pointer. 现在,通过将对象A创建为指针,并将其传递到对象B的两个实例中,使它们全部工作,它们都有自己的指针,然后该指针指向内存中与对象A的指针相同的位置。 This works fine, but I think that's a pretty big No-No right? 这很好用,但是我认为那是一个很大的禁止,对吧? Because once Class A deletes the original pointer I'll have some dangling pointers, right? 因为一旦A类删除了原始指针,我就会有一些悬空的指针,对吗? Is there a better way to do this? 有一个更好的方法吗?

(FYI - Object A takes a couple seconds to load at a time in the program where I need a fast load time, that's why I have to create only one instance and pass it to both of Object Bs instead of letting Object B create their own instances of Object A. ) (仅供参考-对象A一次需要花费几秒钟的时间来加载程序,因此我只需要创建一个实例并将其传递给两个对象B,而不是让对象B创建自己的实例即可对象A的实例。)

If I follow you correctly, you want something like this: 如果我正确地遵循了您的要求,则您需要以下内容:

// Class for "Object A" in your question
class Foo
{
    // ...
};

// Class for "Object B" in your question
class Bar
{
    Foo &foo_;

public:
    Bar(Foo &foo)
        : foo_(foo)
        {}
};

class A
{
    Foo foo_;
    Bar bar1_;
    Bar bar2_;

public:
    A()
        : bar1_(foo_),
          bar2_(foo_)
        {}
};

Using no pointers, no allocations, so no dangling pointers/references or memory leaks. 不使用指针,不分配,因此没有悬空的指针/引用或内存泄漏。 When A gets destroyed so does bar1_ and bar2_ too along with foo_ , so the two instances of Bar will not be left with any dangling references either. A被破坏,从而不会bar1_bar2_沿太foo_ ,这样的两个实例Bar将不会与任何悬挂引用来留着。

Provided that the "B-things" don't outlive the "big object that they both have a pointer to", then you won't have a dangling pointer when the "big object" is deleted. 只要“ B事物”没有超过“它们都有指针的大对象”的寿命,那么删除“大对象”时就不会有悬空的指针。

If "one instance of Class A" has both of those objects as data members, then they'll all be destroyed at the same time (well, in reverse order that they're declared in the class, but close to the same time), so it should be reasonably easy to ensure that the dangling pointer is never used. 如果“类A的一个实例”具有这两个对象作为数据成员,则它们将同时被销毁(嗯,与它们在类中的声明顺序相反,但接近同一时间) ,因此应该很容易确保不使用悬空指针。

On the other hand, if you pass pointers to the "big object" around willy-nilly, store them in all sorts of different places with unknown lifetimes, and then delete the "big object" -- sure, that's a no-no. 另一方面,如果在Willy-nilly周围传递指向“大对象”的指针,则将它们存储在生命周期未知的各种不同位置,然后删除“大对象”-当然,这是不行的。 The problem is "willy-nilly" - you need to keep control and make sure that the big object outlives the objects that point to it. 问题是“意志薄弱”-您需要保持控制力,并确保大对象的寿命超过指向它的对象的寿命。

For example, the following is perfectly safe: 例如,以下内容绝对安全:

struct Big {
    // big stuff
};

struct Little {
    Little(const Big *a) : bigthing(a) {}
    // stuff that uses bigthing
  private:
    const Big *bigthing;
};

struct Foo {
    Big onlybigthing;
    Little firstlittlething;
    Little secondlittlething;
    Foo() : 
        onlybigthing(), 
        firstlittlething(&onlybigthing), 
        secondlittlething(&onlybigthing) 
    {}
};

provided of course that the instances of Little don't hand out their pointer to Big , to anyone who comes asking for it and then stores it beyond the lifetime of the Foo object. 当然,前提是Little的实例不会将指向Big的指针分发给任何提出要求的人,然后将其存储到Foo对象的生存期之外。 Likewise Foo has to avoid handing out copies of the instances of Little to someone who might store those (and the pointer with them). 同样, Foo必须避免将Little实例的副本分发给可能存储这些实例的人(以及与它们一起存储的指针)。

But you say that your class A has two members, whereas here I have three (one Big and two Little ) because you also say that you create three instances of those two objects. 但是您说您的类A有两个成员,而这里我有三个成员(一个Big和两个Little ),因为您还说您创建了这两个对象的三个实例。 I don't understand what that means. 我不明白那是什么意思。

Here's another example of something that's safe: 这是另一个安全的示例:

int main() {
    Big big;
    Little little1(&big);
    Little little2(&big);
}

Here's a third example of something that's safe: 这是安全的第三个例子:

struct Little {
    Little(const std::shared_ptr<Big> &a) : bigthing(a) {}
    // stuff that uses bigthing
  private:
    std::shared_ptr<Big> bigthing;
};

int main() {
    std::shared_ptr<Big> big(new Big());
    Little little1(big);
    Little little2(big);
    big.reset(); // release our shared ownership
    // safely do stuff using little1 and little2

    return 0;
    // on exit, little2 is destroyed first, then when little1 is destroyed
    // it releases the last shared ownership of the instance of `Big`,
    // which is destroyed.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM