C++类foo重载operator=实现复制名称保留唯一ID的方案问询
问题分析与修正方案
你的现有实现不可行,核心问题和调整方案如下:
核心逻辑误区
foo f2 = f1;属于拷贝初始化语法,调用的是拷贝构造函数而非赋值运算符,你已经将拷贝构造显式=delete,这行代码本身首先就会编译失败。如果需要支持这种写法,不能删除拷贝构造,应该自定义拷贝构造逻辑,仅复制名称、生成新ID;如果确定要保留拷贝构造删除的限制,就不能用这种初始化写法,只能使用已创建对象的赋值场景:foo f2("temp"); f2 = f1;。
现有代码的语法错误
- 没有包含
<string>头文件,且string类属于std命名空间,需要加std::前缀,否则编译不通过 - 构造函数中
MaxID++后缺少分号 - 静态成员
MaxID仅在类内声明,没有类外初始化,会报链接错误 - 成员函数
getName、setName没有声明返回值类型,C++不允许函数无返回值声明 - 赋值运算符中调用成员函数的语法错误:
this是指针,需要用->访问成员,且函数调用要加括号,this.setName(right.getName)需要改为this->setName(right.getName()) - 没有加自赋值判断,出现
f1 = f1这种自赋值场景时会做无意义操作
修正后的完整实现
#include <iostream> #include <string> class foo { private: static int MaxID; int ID; std::string Name; public: // 普通构造函数 foo(std::string l_Name):Name(std::move(l_Name)), ID(MaxID) { MaxID++; } // 自定义拷贝构造,支持foo f2 = f1写法,仅复制名称、生成新ID,不需要的话可以删除这行换成=delete foo(const foo& other): Name(other.Name), ID(MaxID) { MaxID++; } // 禁用拷贝构造的话放开下面这行注释,同时不能使用foo f2 = f1的初始化写法 // foo(const foo&) = delete; // 重载赋值运算符,仅复制名称,保留当前对象原有ID foo& operator=(const foo& right) { if (this == &right) return *this; // 自赋值直接返回 Name = right.Name; return *this; } std::string getName() const { return Name; } void setName(std::string TempName) { Name = std::move(TempName); } int getID() const { return ID; } }; // 静态成员类外初始化 int foo::MaxID = 0;
验证测试
int main() { foo f1("Name1"); // 拷贝初始化场景(需要保留自定义拷贝构造) foo f2 = f1; std::cout << "f1 信息:ID=" << f1.getID() << ",Name=" << f1.getName() << "\n"; std::cout << "f2 信息:ID=" << f2.getID() << ",Name=" << f2.getName() << "\n"; // 赋值场景 foo f3("Name3"); std::cout << "赋值前f3 信息:ID=" << f3.getID() << ",Name=" << f3.getName() << "\n"; f3 = f1; std::cout << "赋值后f3 信息:ID=" << f3.getID() << ",Name=" << f3.getName() << "\n"; return 0; }
测试输出可以看到,无论是拷贝初始化还是赋值操作,目标对象的ID都和源对象不同,名称保持一致,完全符合需求。
内容的提问来源于stack exchange,提问作者Finn
相关产品推荐
相关产品推荐

