如何分辨另一个物体死亡的对象
How to tell the object of the death of another object?
在我的工作中,我遇到了一个错误,可以描述如下。有两个类,A类和B类:
class A
{
public:
void print(){}
};
class B
{
A* a;
public:
void init(A* _a) {
a = _a;
}
void PrintWithA()
{
a->print();
}
};
A* a;
B* b;
b->init(a);
// some code .....
delete a; // line 1
a = NULL;
// some code .....
b->PrintWithA(); // line 2
对象"b"对对象"a"的状态一无所知。 在第 1 行中,"a"对象已被删除,但在第 2 行,我们继续使用它。当有很多代码时,很容易犯这样的错误。我的问题是以下 - 使用哪种方法来避免一些错误?我想我可以使用观察者模式 - 但我认为这是不合理的昂贵解决方案。谢谢。
你应该使用弱 ptr (http://en.cppreference.com/w/cpp/memory/weak_ptr)
基本上你可以提供 B 类的弱 PTR 为 A。
每当需要访问 A 时,您可以尝试锁定弱 ptr 以查看它是否仍然有效。
#include <memory>
class A
{
public:
void print(){}
};
class B
{
std::weak_ptr<A> a;
public:
void init(std::weak_ptr<A> _a) {
a = _a;
}
void PrintWithA()
{
if (auto spt = a.lock()) {
spt->print();
}
}
};
int main()
{
std::shared_ptr<A> a = std::make_shared<A>();
std::unique_ptr<B> b = std::make_unique<B>();
b->init(a);
// some code .....
a = nullptr;
// some code .....
b->PrintWithA(); // line 2
return 0;
}
为了防止这种情况,要么 B 需要在构造对象 B 时获得 A 生存期的所有权,要么您需要对 A 引用进行计数。
C++11 我认为有一个共享指针的概念,它维护引用,如果有人有引用,将防止对象 A 被删除。 见std::shared_ptr
如果您不使用 C++11,则boost::shared_ptr
基本上可以执行相同的操作。 但是你需要我个人不喜欢使用的提升库,但这取决于你。
像这样使用它们:
typedef std::shared_ptr<A> A_ptr;
A_ptr a = new A();
class B
{
A_ptr a;
public:
void B(A_ptr _a) {
a = _a;
}
void PrintWithA()
{
a->print();
}
};
否则你可以自己把一些东西放在一起。 大致如下:
class A
{
public:
A(){
ref_count = 1;
}
void print(){}
void grab() {
ref_count++;
}
void release() {
ref_count--;
if (ref_count <= 0)
~A();
}
private:
int ref_count;
~A(){
delete this;
}
};
在 B 中,您将分配指针并调用 grab();
而不是调用删除(这不起作用,因为它是私有的),你会调用指针上的 a->release()。
现在这不是特别好,因为你不能使用这种形式:
A a;
所以这并不理想。 但是,如果您使用的是某些没有shared_ptr的编译器,并且您不介意限制,则可以使用它或它的一种形式。 通常,使用shared_ptr。
首先,说A* a;
的行可能应该A* a = new A;
.
在 c++ 中,您需要显式编码此意识,它不会自动完成。
您可以做的一件事是检查_a
在 PrintWithA
中是否为 NULL,但如果您确保在delete[]
后始终将指针设置为 NULL,这将不起作用(您已经这样做了)
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- 为什么我不能将一个对象push_back到属于另一个类的对象向量中?
- 在他自己的方法中,有可能将一个对象取消引用到另一个对象吗
- 如果C++对象的类在另一个boost模块中声明,如何使用boost将指向该对象的指针返回到python
- 为什么C++在将一个对象复制到另一个对象时需要对这两个对象进行低级常量限定
- 检查哪个对象调用了另一个对象的对象方法
- C++ 如何在将新对象分配给另一个对象时创建新对象
- 如何处理从一个对象传递到另一个在C++中具有公共抽象类的对象的消息
- 为什么我可以在不重载 "=" 运算符的情况下将一个对象分配给另一个对象?
- 如何在qt中将信号和插槽与另一个对象连接 --解决了
- 为什么我不能在主函数之外定义一个类的对象(它继承了另一个类)?
- Qt:从另一个窗口访问公共对象
- 是否可以使用一个类来控制 C++ 中另一个类的对象?(阿杜伊诺)
- C++:将初始化的对象传递给另一个类的构造函数;需要不必要的构造函数吗?
- 将另一个类的对象传递到当前类C++的构造函数中(不是成员初始化)
- 结束另一个线程中使用的对象的生存期
- 如何将我编写的对象传递到另一个类的构造函数中?
- 在 C++ 中将一个模板类型的对象类型转换为另一个模板类型
- 在C++中将对象从另一个类传递到另一个类的构造函数?
- 删除对象(另一个..)时双重释放或损坏