我有一个A类实例。它有两个成员,对象A和对象B.我需要创建一个对象A的实例(这是一个非常大的对象),以及对象B的两个实例,然后给出对象B的两个实例都访问该对象A.他们不需要更改对象A,他们只需要访问它的信息。
现在,我通过将对象A创建为指针,将其传递到对象B的两个实例中来完成所有工作,对象B具有自己的指针,然后指向内存中与对象A的指针相同的位置。这很好用,但我认为这是一个非常大的No-No对吗?因为一旦A类删除原始指针,我就会有一些悬空指针,对吧?有一个更好的方法吗?
(仅供参考 - 对象A需要几秒钟才能在我需要快速加载时间的程序中加载,这就是为什么我必须只创建一个实例并将其传递给两个对象B而不是让对象B创建自己的Object A实例。)
答案 0 :(得分:2)
如果我正确地关注你,你需要这样的东西:
// 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_)
{}
};
不使用指针,不使用分配,因此没有悬空指针/引用或内存泄漏。当A
被破坏时,bar1_
和bar2_
以及foo_
也会被破坏,因此Bar
的两个实例也不会留下任何悬空引用。
答案 1 :(得分:1)
如果“B-things”没有超过“他们都有指针的大对象”,那么当删除“大对象”时你就不会有悬空指针。
如果“A类的一个实例”将这两个对象都作为数据成员,则它们将同时被销毁(嗯,与它们在类中声明的相反顺序,但接近于同时),因此确保从不使用悬空指针应该相当容易。
另一方面,如果你将指针传递给willy-nilly周围的“大对象”,将它们存储在生命未知的各种不同的地方,然后删除“大对象” - 当然,这是一个不-没有。问题是“无所畏惧” - 你需要保持控制并确保大对象比指向它的对象更长。
例如,以下内容非常安全:
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)
{}
};
当然提供Little
的实例不会将指针发送给Big
,而是要求提供它的人,然后将其存储在Foo
的生命周期之外宾语。同样,Foo
必须避免将Little
实例的副本分发给可能存储这些实例的人(以及指向它们的指针)。
但是你说你的A类有两个成员,而在这里我有三个(一个Big
和两个Little
),因为你还说你创建了三个实例这两个对象。我不明白这意味着什么。
这是另一个安全的例子:
int main() {
Big big;
Little little1(&big);
Little little2(&big);
}
以下是安全事项的第三个例子:
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.
}