Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 重载实现的虚函数_C++ - Fatal编程技术网

C++ 重载实现的虚函数

C++ 重载实现的虚函数,c++,C++,假设我有一个类Foo class Foo{ public: bool virtual bar(){return false;} }; 类foooo继承Foobar()在类foooo中不被重写。我无法更改Foo或foooo的标题。那么是否可以覆盖foooo中的bar()的默认实现?否。只能通过在派生类的定义中声明覆盖来覆盖函数。否。您需要在foooo类定义中声明覆盖,您说您不能这样做。如果您试图在类之外的foooo中定义被重写的函数,您会遇到错误,因为它以前没有在foooo中声明为

假设我有一个类
Foo

class Foo{
  public:
     bool virtual bar(){return false;}
};

foooo
继承
Foo
bar()
在类
foooo
中不被重写。我无法更改
Foo
foooo
的标题。那么是否可以覆盖
foooo
中的
bar()
的默认实现?

否。只能通过在派生类的定义中声明覆盖来覆盖函数。

否。您需要在
foooo
类定义中声明覆盖,您说您不能这样做。如果您试图在类之外的
foooo
中定义被重写的函数,您会遇到错误,因为它以前没有在
foooo
中声明为被重写

还要注意,在C++11及更高版本中,应该使用
override
属性。例如:

struct FooFoo : Foo
{
    bool bar() override { return true; }
};

这是不可能的,;可以说,不修改类就不能修改它


您最好的选择是公开从代码< > FooOf和在派生类中重写.< /P> < P>在C++语言中,特别是实现,在技术上可以手动修改类<代码> FoFoO< /Co>的VTABLE,并将指针替换为代码> Fo::Bar()//>代码>其他内容。当然,这将是一个丑陋的黑客行为,在任何意义上都不是推荐的做法,也不保证在某些事情发生变化(例如编译标志)时也能工作

那么,是否有可能覆盖的默认实现 FooFoo中的bar()

不,但是您可以派生另一个类,并通过基类“多态地”使用该类。这应该具有相同的效果,因为Foo的原始客户机是通过Foo的接口进行工作的,他应该这样做

因此:

//In Foo.h - may not be modified
struct Foo
{
  virtual bool bar(){ return true;}
};

//In FooFoo.h - may not be modified, hence no override...
struct FooFoo: public Foo
{
  virtual bool bar(){/**/}
};

//FooFoo_2 - The new class - may be implemented in terms of FooFoo
struct FooFoo_2: public Foo
{
  virtual bool bar() override{/*new implementation*/}
};

void fooUser( Foo& foo )
{
  bool result = foo.bar();
  if (result ){} //etc
}

int main()
{
  FooFoo_2 theNewImplementation;
  fooUser( theNewImplementation );
  return 0;
}
还需要注意的是,不需要“重写”,但是如果添加了“重写”,那么如果bar的签名在base中发生了更改(这将导致派生不再是虚拟的),就会出现编译器错误—这是需要注意的


关于

您缺少继承,在您的示例中不应覆盖foooo。除了这里给出的答案之外,您还可以使用“装饰器模式”,它不直接提供问题的答案,而是提供解决方案的替代方法。