C++抽象类与继承问题:map函数执行结果不符合预期
听起来你遇到的是典型的对象切片或者虚函数调用失效的问题,结合你描述的现象——test1能正常工作,test2却直接返回原vector,大概率是这几个原因之一:
1. 运算符重载的参数是值传递,导致对象切片
如果你的operator-是这么写的:
vector<int> operator-(const vector<int>& lhs, Transform rhs) { return rhs.map(lhs); }
这里的Transform rhs是值传递,当你传入DoubleElements对象时,会被切割成基类Transform对象。如果基类的map函数有默认实现(比如直接返回输入vector),那自然不会处理你的数据。
修复方式:把参数改成const Transform& rhs(引用传递),这样就不会触发切片,能正确调用派生类的map重写:
vector<int> operator-(const vector<int>& lhs, const Transform& rhs) { return rhs.map(lhs); }
2. 基类的map函数不是虚函数
如果基类的map没有声明为virtual,哪怕你在派生类里重写了它,通过基类引用调用时也会触发静态绑定,执行基类的map版本。必须确保基类的map是虚函数:
class BaseTransform { public: // 纯虚函数强制派生类实现,也可以带默认实现 virtual vector<int> map(const vector<int>& input) const = 0; };
3. DoubleElements的拷贝/赋值逻辑有问题
如果你复用同一个DoubleElements对象,或者创建新对象时,映射函数f没有被正确复制——比如f是std::function或函数指针类型的成员变量,而你的拷贝构造函数/赋值运算符没有处理它,导致test2的f处于默认状态(比如空函数,直接返回原数值)。
检查点:确保DoubleElements的拷贝逻辑正确复制f:
class DoubleElements : public BaseTransform { private: std::function<int(int)> f; public: DoubleElements(std::function<int(int)> func) : f(std::move(func)) {} // 手动实现拷贝构造,复制f DoubleElements(const DoubleElements& other) : f(other.f) {} // 赋值运算符同理 DoubleElements& operator=(const DoubleElements& other) { if (this != &other) { f = other.f; } return *this; } vector<int> map(const vector<int>& input) const override { vector<int> res; for (int num : input) { res.push_back(f(num)); } return res; } };
4. test2的初始化有误
最后再确认下test2的初始化代码,是不是和test1一样设置了正确的映射函数f?比如有没有不小心用了默认构造(DoubleElements test2;),导致f为空,而test1是带参构造(比如DoubleElements test1([](int x){ return x*2; });)?
按照这几个方向排查,应该能快速定位问题。
内容的提问来源于stack exchange,提问作者Athena

