C++对象实例销毁后仍留存于列表中的问题求助
分析你的Member类问题与修复方案
首先我先把你没写完的类定义补全,整理出完整的框架(推测你原本要写follow和unfollow成员函数):
// Member.h #include <list> using namespace std; class Member { private: bool isCopy; static int counter; int id; list<Member*> following; list<Member*> followers; public: Member(); Member(const Member &p2); ~Member(); void follow(Member& other); void unfollow(Member& other); // 补充常用的统计方法 int getFollowingCount() const; int getFollowersCount() const; };
接下来我针对社交网络成员类常见的坑,逐一分析并给出修复方案:
1. 静态计数器的初始化问题
静态成员变量必须在类外部初始化,否则编译时会出现链接错误。你需要在Member.cpp中添加:
int Member::counter = 0;
2. 拷贝构造函数的风险
你定义了isCopy成员,应该是想区分原生对象和拷贝对象,但拷贝这类包含指针列表的对象很容易出问题——比如拷贝后的对象会和原对象共享同一批关注/粉丝指针,析构时会触发double free。
在社交网络场景下,成员对象应该是唯一的,更合理的做法是直接禁用拷贝:
// 在类的public区域添加 Member(const Member&) = delete; Member& operator=(const Member&) = delete;
如果确实需要拷贝,必须实现深拷贝,但这在实际业务逻辑里意义不大,毕竟没人会需要一个和原账号完全一样的副本。
3. follow函数的双向逻辑错误
关注操作必须是双向的:当前成员要把对方加入自己的following列表,同时对方要把当前成员加入followers列表,不然粉丝数和关注数会完全对不上。
正确的实现:
#include <algorithm> // 需要用到find函数 void Member::follow(Member& other) { // 禁止关注自己 if (this == &other) return; // 检查是否已经关注过,避免重复添加 auto it = find(following.begin(), following.end(), &other); if (it == following.end()) { following.push_back(&other); other.followers.push_back(this); } }
4. unfollow函数的双向移除逻辑
取消关注同样要做双向操作:从自己的following中移除对方,同时从对方的followers中移除自己。
正确的实现:
void Member::unfollow(Member& other) { if (this == &other) return; // 利用list的remove方法直接移除指定指针 following.remove(&other); other.followers.remove(this); }
5. 析构函数的注意事项
你的following和followers列表里存的是指向其他Member对象的指针,但这些对象不是当前对象创建的(通常是独立在堆上new出来的),所以析构函数里绝对不能delete这些指针,否则会导致其他对象被提前销毁,引发未定义行为。
如果需要在成员销毁时清理关联关系,可以这么写:
Member::~Member() { // 通知所有被我关注的人,移除我在他们粉丝列表里的记录 for (auto followed : following) { followed->followers.remove(this); } // 通知所有我的粉丝,移除我在他们关注列表里的记录 for (auto follower : followers) { follower->following.remove(this); } // 清空自己的列表 following.clear(); followers.clear(); counter--; // 如果counter是统计当前活跃成员数的话 }
6. 构造函数的实现
构造函数需要初始化id和计数器:
Member::Member() : isCopy(false), id(++counter) { // 列表会默认初始化为空,不需要额外操作 }
补充:统计方法的实现
为了方便获取关注数和粉丝数,补充两个成员函数:
int Member::getFollowingCount() const { return following.size(); } int Member::getFollowersCount() const { return followers.size(); }
最后可以用这段代码测试基本逻辑:
#include <iostream> using namespace std; int main() { Member a; Member b; Member c; a.follow(b); a.follow(c); b.follow(a); cout << "a的关注数:" << a.getFollowingCount() << endl; // 输出2 cout << "a的粉丝数:" << a.getFollowersCount() << endl; // 输出1 cout << "b的关注数:" << b.getFollowingCount() << endl; // 输出1 cout << "b的粉丝数:" << b.getFollowersCount() << endl; // 输出1 a.unfollow(b); cout << "a的关注数:" << a.getFollowingCount() << endl; // 输出1 cout << "b的粉丝数:" << b.getFollowersCount() << endl; // 输出0 return 0; }
内容的提问来源于stack exchange,提问作者Tal
相关产品推荐
相关产品推荐

