这是父类Foo
,它是抽象的(虚拟的)。
并且Foo
类'方法在Foo.cpp
中声明。
[foo.h中]
class Foo
{
public:
Foo();
~Foo();
virtual void methodA(int no, const char* path) = 0;
virtual void methodB(const char* name, const char* path) = 0;
virtual void methodC(const char* name, const char* path) = 0;
// ... more 20 virtual methods
}
[Foo.cpp中]
Foo::Foo(){}
Foo::~Foo(){}
Foo::methodA(int no, const char* path)
{
// do something
}
Foo::methodB(const char* name, const char* path)
{
// do something
}
Foo::methodC(const char* name, const char* path)
{
// do something
}
// ... more 20 methods
在Foo
班级中,必须使用参数methodA
调用no
。
此外,参数no
必须从0开始依次增加。
非常不舒服。所以我想覆盖子类methodA
中的Bar
。
Bar
类有一个memeber变量m_no
和methodA
没有参数no
。
调用m_no
时,methodA
会增加。
这是我的代码。
[Bar.h]
class Bar : public Foo
{
public:
Bar();
~Bar();
void methodA(const char* path);
private:
int m_no;
}
[Bar.cpp]
Bar::Bar() : m_no(0) {}
Bar::~Bar() {};
Bar::methodA(const char* path)
{
Foo::methodA(m_no++, path);
}
但是类Bar
是抽象的(虚拟),因为类Bar
不是声明虚拟方法(methodA
,methodB
,methodC
和20种方法更多)。
所以,我编辑了。
[Bar.h]
class Bar : public Foo
{
public:
Bar();
~Bar();
void methodA(const char* path);
void methodB(const char* name, const char* path);
void methodC(const char* name, const char* path);
// ... more 20 methods
private:
int m_no;
}
[Bar.cpp]
Bar::Bar() : m_no(0) {}
Bar::~Bar() {};
Bar::methodA(const char* path)
{
methodA(m_no++, path);
}
Bar::methodA(int no, const char* path)
{
Foo::methodA(no, path);
}
Bar::methodB(const char* name, const char* path)
{
Foo::methodB(name, path);
}
Bar::methodC(const char* name, const char* path)
{
Foo::methodC(name, path);
}
// ... more 20 methods
如何在不声明所有虚拟方法的情况下继承类Foo
?
答案 0 :(得分:2)
如何在不声明所有虚拟方法的情况下继承Foo类?
您为他们提供了实施。
(注意:这部分增加了@TommyA的答案,但评论时间太长;请参阅第二部分,了解不同的方法)
考虑:
class Foo
{
public:
Foo();
virtual ~Foo() = 0; // this is the only pure virtual function
virtual void methodA(int no, const char* path);
virtual void methodB(const char* name, const char* path);
virtual void methodC(const char* name, const char* path);
// ... more 20 virtual methods
}
Foo.cpp中:
Foo::~Foo() = default; // unless you need to add some impleemntation
// other methods implemented like you did
栏:
class Bar : public Foo
{
public:
Bar();
virtual ~Bar();
void methodA(const char* path);
// do not implement anything of Foo here (it is inherited already)
private:
int m_no;
}
第二部分
另一种方法是遵循open-closed principle(决定如果必须以越来越多的数量调用方法,那么Foo有责任实现它,并添加template method implementation) :
class Foo
{
public:
// public interface for methodA, accessible to clients
void methodA(const char* path);
protected:
virtual void methodA_impl(int no, const char* path) = 0;
private:
int m_no; // private: not accesible to specializations
};
void Foo::methodA(const char* path)
{
methodA_impl(m_no++, path);
}
class Bar: public Foo
{
// ...
protected:
void methodA_impl(int no, const char* path) override;
}
void Bar::methodA_impl(int no, const char* path)
{
// Bar-speciffic implementation here
}
这遵循开闭原则,因为“每次通话必须增加数量”要求是固定的,不能被覆盖 特。
Foo特化的客户端无法更改方法调用方法(它总是被正确调用),并且您具有所需的虚方法行为。
答案 1 :(得分:0)
当基类是纯虚拟的时,您希望实例化的子类需要在实例化之前完全实现纯虚方法。但你可以创建一个默认实现方法的“中间”层,然后继承这些方法。
注意:请记住使用虚拟析构函数创建非最终类。
答案 2 :(得分:0)
该类Foo
的重点已定义,因此所有派生类必须覆盖所有纯虚方法。
最明显的解决方法是向任何提供课程Foo
的人抱怨并让他们提供合理设计的基类。以这种方式定义类是绝对糟糕的设计,除非显然必须覆盖所有虚函数。它也是一个糟糕的设计(因为有些情况下结果是未定义的行为)有一个没有虚拟析构函数的基类。
如果这是您的设计,请重新设计整个类层次结构。说真的,设计很差。
但是,可以简单地从Foo
派生另一个类并覆盖所有必需的成员函数。例如;
class FooIntermediary : public Foo
{
virtual void methodA(int no, const char* path);
virtual void methodB(const char* name, const char* path);
virtual void methodC(const char* name, const char* path);
};
void FooIntermediary::methodA(int no, const char *path)
{
Foo::methodA(no, path);
}
void FooIntermediary::methodB(const char *name, const char *path)
{
Foo::methodB(name, path);
}
// etc
然后,任何派生自FooIntermediary
的类都将被强制覆盖Foo
未覆盖的FooIntermediary
中的任何继承函数。
你可以找到另一个派生自Foo
的类,它可以被实例化,并且(除了你寻求的特定变化之外)你需要的所有行为。根据定义,该类将覆盖所有继承的抽象函数。因此,从中派生一个类,并仅覆盖您需要的虚函数。