C++堆内存队列指针赋值失效:如何实现两个类共享同一队列?
问题:让两个类共享同一个队列指针的正确方式
我正在编写C++示例代码,希望让两个类能够访问同一个队列,但调用connectMQ函数后,a_Object.ToMQ和b_Object.FromMQ并未指向与messageQueue1Send相同的堆内存地址,函数内的赋值仅在函数作用域内有效。请问如何正确完成指针赋值,解决该错误,确保仅访问堆内存地址?
原代码如下:
#include <iostream> #include <queue> using namespace std; class MessageQueue{ public: std::queue<int> m_queue; }; class A_Object{ public: MessageQueue *ToMQ=0; }; class B_Object{ public: MessageQueue *FromMQ=0; }; void connectMQ(MessageQueue *original, MessageQueue *source, MessageQueue *destination); void connectMQ(MessageQueue *original, MessageQueue *source, MessageQueue *destination){ source = original; destination = original; // source and destination has the same addresses as original } int main() { cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!! MessageQueue *messageQueue1Send; messageQueue1Send = new MessageQueue(); A_Object a_Object; B_Object b_Object; connectMQ(messageQueue1Send, a_Object.ToMQ, b_Object.FromMQ); // at this point the addresses of a_Object.ToMQ and b_Object.FromMQ dont show to the same adress on the heap like messageQueue1Send messageQueue1Send->m_queue.push(10); int value = b_Object.FromMQ->m_queue.front(); cout << "value="<< value << endl; return 0; }
错误原因
你的connectMQ函数参数是指针传值,这意味着函数内部的source和destination只是外部指针的副本。在函数里修改副本的指向,不会影响外部原本的a_Object.ToMQ和b_Object.FromMQ的指向,所以函数结束后外部指针依然是初始的空指针。
解决方案
要修改外部的指针,需要传递指针的指针或者指针的引用,这样函数内部才能直接操作外部的指针变量。
方案1:使用指针的指针
修改connectMQ的参数和实现:
#include <iostream> #include <queue> using namespace std; class MessageQueue{ public: std::queue<int> m_queue; }; class A_Object{ public: MessageQueue *ToMQ=0; }; class B_Object{ public: MessageQueue *FromMQ=0; }; // 参数改为指针的指针 void connectMQ(MessageQueue *original, MessageQueue **source, MessageQueue **destination); void connectMQ(MessageQueue *original, MessageQueue **source, MessageQueue **destination){ // 通过指针的指针修改外部指针的指向 *source = original; *destination = original; } int main() { cout << "!!!Hello World!!!" << endl; MessageQueue *messageQueue1Send = new MessageQueue(); A_Object a_Object; B_Object b_Object; // 传入指针的地址 connectMQ(messageQueue1Send, &a_Object.ToMQ, &b_Object.FromMQ); messageQueue1Send->m_queue.push(10); // 此时b_Object.FromMQ已经正确指向目标队列 int value = b_Object.FromMQ->m_queue.front(); cout << "value="<< value << endl; // 记得释放堆内存,避免泄漏 delete messageQueue1Send; return 0; }
方案2:使用指针的引用
C++支持引用,用指针的引用可以更直观地操作外部指针:
#include <iostream> #include <queue> using namespace std; class MessageQueue{ public: std::queue<int> m_queue; }; class A_Object{ public: MessageQueue *ToMQ=0; }; class B_Object{ public: MessageQueue *FromMQ=0; }; // 参数改为指针的引用 void connectMQ(MessageQueue *original, MessageQueue* &source, MessageQueue* &destination); void connectMQ(MessageQueue *original, MessageQueue* &source, MessageQueue* &destination){ // 直接修改引用对应的外部指针 source = original; destination = original; } int main() { cout << "!!!Hello World!!!" << endl; MessageQueue *messageQueue1Send = new MessageQueue(); A_Object a_Object; B_Object b_Object; // 直接传入指针变量(引用会绑定到外部变量) connectMQ(messageQueue1Send, a_Object.ToMQ, b_Object.FromMQ); messageQueue1Send->m_queue.push(10); int value = b_Object.FromMQ->m_queue.front(); cout << "value="<< value << endl; delete messageQueue1Send; return 0; }
补充说明
- 两种方案都能实现需求,指针引用的写法更简洁直观,是C++里更推荐的方式。
- 注意最后要释放
messageQueue1Send指向的堆内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者AndreStony
相关产品推荐
相关产品推荐

