-4

我目前在使用基类中定义为 const 的函数时遇到问题。

我正在使用上述虚函数实现派生类,但返回值是非 const。我想在不更改基类的情况下实现它,因为还有其他外部类使用这个虚函数。不更改此虚函数的原因是存在使用相同函数的其他派生类。

非常感谢任何帮助。

例如:我正在实现double DerivedClass1::Function()具有不同返回值的派生类函数,该函数是在double BaseClass::Function() const. 同样的功能由我使用double DerivedClass2::function() constdouble DerivedClass3::Function() const我无法控制。如何在不对基类进行任何或最小更改的情况下做到这一点。

4

3 回答 3

1

我不确定我是否完全理解你,但也许这就是你想要的:

struct BaseClass {
    virtual double Function() {return const_cast<const BaseClass*>(this)->Function();}
    virtual double Function() const=0;
    virtual BaseClass() {}
};
struct DerivedClass1: public BaseClass {
    virtual double Function() {stuff};
    virtual double Function() const {throw std::logic_error("UNIMPLEMENTED");};
};
struct DerivedClass2: public BaseClass {
    virtual double Function() const {stuff};
};

不用说,这是一个非常糟糕的主意。BaseClass 实现会将可变实例重定向到现有const函数,除非它们已被派生类覆盖,正如您在DerivedClass1. 问题是如果你调用Function()a const DerivedClass1,那么你会在运行时得到一个异常。

于 2012-08-08T23:33:22.087 回答
1

你有:

struct Base {
    virtual double Function() const;
};

struct Derived1 : Base {
    virtual double Function() const;
};

struct Derived2 : Base {
    virtual double Function() const;
};

你要:

struct Derived1 : Base {
    virtual double Function(); // overrides virtual function in base
};

所以,首先你需要添加一个非常量虚函数到Base,否则你不会覆盖任何东西。问题是,基类函数应该定义为什么?为了最小化中断,它应该做与当前通过非常量引用调用函数相同的事情——调用 const 函数:

struct Base {
    virtual double Function() const;
    virtual double Function() { return static_cast<const Base*>(this)->Function(); }
};

struct Derived1 : Base {
    virtual double Function() const;
    virtual double Function();
};

struct Derived2 : Base {
    virtual double Function() const;
    // no need to override non-const Function
};

我认为这仍然可能会破坏现有代码,例如,如果您将指针指向函数的 const 和非 const 版本,那么以前它们会比较相等,而现在它们不会:

typedef double (Base::*constfunc)() const;
typedef double (Base::*mutfunc)();
((mutfunc)(constfunc(&Base::Function)) == (mutfunc(&Base::Function))); // was true, now false

对于该类的典型用户Base,添加新功能可能是无害的。

double但是,您说:“使用上述虚函数但具有非 const 返回值”,并且您的示例函数即使使用 const 版本的函数也已经具有非 const 返回值 ( )。所以答案无法解决这个问题,而且通过隐藏你的真实用例,你得到的答案可能比你通过一个更好地反映你的实际代码的例子得到的答案更糟糕。

于 2012-08-08T23:48:20.727 回答
0

想要覆盖虚拟基方法的派生方法必须使用与基方法完全相同的签名,包括使用 of const,否则派生方法将仅隐藏基方法而不是覆盖它。如果您打算重写,则不能更改派生类中的签名。

于 2012-08-08T23:22:35.310 回答