在转换运算符重载时不会调用重载方法

时间:2014-10-29 20:13:53

标签: c++ oop inheritance polymorphism

我有一个包含virtual方法和强制转换操作符的基类:

class Base {
public:
    Base() {}
    operator int() const { return getInt(); }
protected:
    virtual int getInt() const { return 0; }
}

然后我有两个覆盖虚方法的派生类:

class Derived1 {
public:
    Derived1() : Base() {}
protected:
    virtual int getInt() const override { return 1; }
}

class Derived2 {
public:
    Derived2() : Base() {}
protected:
    virtual int getInt() const override { return 2; }
}

然后我有一个辅助功能:

Base helper(const bool flag) {
    if (flag)
        return Derived1();
    else
        return Derived2();
}

该辅助函数的用意如下:

int one = helper(true); // I expect "one" to be 1
int two = helper(false); // I expect "two" to be 2

onetwo都包含0。我不知道如何解决这个问题。在Derived类完全构造之前,是否会调用强制转换运算符?我的环境是VS2013。


建议修复(在我的情况下,在回答后)

我最终将helper函数转换为class,将Derived存储为成员并返回对它们的引用(我认为这实际上是一个更好的设计,因为每个{ {1}}调用[]未构造/分配):

Derived

旁注

接受的答案表明问题的要点是在引用(如Python)中思考所有事情,这是事实。这个问题是一个更大的系统设计的一部分,它允许在C ++中使用类似Python的语法访问从SQLite数据库返回的结果。链接方括号如:class Helper { public: Helper(); const Base& get(const bool flag) const { if (flag) return mDerived1; else return mDerived2; } private: Derived1 mDerived1; Derived2 mDerived2; }

1 个答案:

答案 0 :(得分:3)

您的helper函数按值返回Base,它会删除您在函数内创建的对象的任何派生函数,从而导致虚方法调用基本版本。

编辑:我看到这个已被标记为重复,但重复,在解释问题时,似乎没有明确提供这个特定问题的一个很好的解决方案。

答案的要点是你可能习惯于像Python或Java这样的语言,其中一切都是引用(我在使用这些语言时犯了相反的错误)。在C ++中,除非您指定所有内容,否则一切都是按值进行的,并且当按值返回时,切片问题会出现。

您要做的是在堆上分配适当的派生类型,并从helper函数返回指向该对象的智能指针。智能指针将确保您不会泄漏内存,并通过返回指针而不是按值返回,确保多态在程序中仍然有效。