我有一个抽象类Job和其他实现它的类,比如:waiter
和builder
,它们都以相同的方式实现我的功能,例如:
Waiter::changeScore()
{
score += top_score;
}
我该如何防止代码重复呢? 注意:
>
我要将作业
保留为抽象
每个waiter或builder都有自己的top_score值(它在类和相同类的对象之间不同)
并不是抽象类的所有成员函数都需要是纯虚拟的(只要至少有一个是)。 您的ChangeScore
成员是作为“真实”基类函数的理想候选。 此外,它不仅不需要是纯的virtual
,甚至根本不需要是virtual
(除非您希望您的多态性改变指向派生类的指针对于该函数将看到的内容)。
由于每个类(或对象)都有自己的top_score
值(如您所述),因此(data)成员也可以是'abstract'基类的一部分。
您甚至可以在基类中添加一个单一的“dummy”纯虚拟函数(它从来不打算使用,甚至是派生类),只是为了确保不会意外地创建实例。 例如,job
类可以有一个成员:
virtual int Dummy() = 0;
然后,任何派生类都必须有一个重写(无论多么微不足道),否则编译器将不允许您声明该类的实例。 因此,您的waiter
类需要如下内容:
int Dummy override { return 1; }
下面的代码示例可能有助于/演示这个想法:
#include <iostream>
#include <memory> // So we can use smart pointers
class Job {
public:
int score{ 0 }, top_score{ 0 };
public:
Job() { }
virtual ~Job() = default;
virtual void Dummy() = 0; // This is sufficient to make the class abstract!
void changeScore() {
score += top_score;
}
virtual void showName() {
std::cout << "Generic Job" << std::endl;
}
};
class Waiter : public Job {
public:
Waiter(int top = 5) { top_score = top; }
~Waiter() override = default;
void Dummy() override { } // We need this in order to use Waiter
void showName() override {
std::cout << "Waiter" << std::endl;
}
};
class Builder : public Job {
public:
Builder(int top = 10) { top_score = top; }
~Builder() override = default;
void Dummy() override { } // We need this in order to use Builder
void showName() override {
std::cout << "Builder" << std::endl;
}
};
int main()
{
Waiter w{ 6 }; // OK - uses explicit value for 'top' parameter
Builder b; // OK - uses default value for 'top' parameter
// Job j; // ERROR - Cannot instantiate abstract class
w.changeScore();
b.changeScore();
std::cout << w.score << std::endl;
std::cout << b.score << std::endl;
// Also, using pointers...
// Job* pj = new Job; // ERROR - Cannot instantiate abstract class
Job* pw = new Waiter; // OK - Now we can make use of polymorphism...
Job* pb = new Builder; // ...with either of these 2 "Job" pointers!
pw->showName();
pb->showName();
delete pw;
delete pb;
// Polymorphism also works with smart pointers (which you SHOULD be using) ...
// std::unique_ptr<Job> upj = std::make_unique<Job>(); // ERROR - Allocating an object of abstract class
std::unique_ptr<Job> upw = std::make_unique<Waiter>(15);
upw->changeScore();
std::cout << upw->score << ": ";
upw->showName();
std::unique_ptr<Job> upb = std::make_unique<Builder>(42);
upb->changeScore();
std::cout << upb->score << ": ";
upb->showName();
return 0;
}
可以在基类中定义方法:
现场演示
class Job
{
virtual void some_method() = 0; //one pure virtual method, abstract class
public:
void changeScore() {
score += top_score;
}
virtual ~Job(){}
};
class Waiter : public Job {
void some_method() override{}
};
class Buider : public Job{
void some_method() override{}
};
ChangeScore()
将在抽象类中实现,所有派生的类都可以使用。