提问者:小点点

如何在一个抽象基派生的类中实现同样的方法?


我有一个抽象类Job和其他实现它的类,比如:waiterbuilder,它们都以相同的方式实现我的功能,例如:

Waiter::changeScore()
{
    score += top_score;
}

我该如何防止代码重复呢? 注意:

>

  • 我要将作业保留为抽象

    每个waiter或builder都有自己的top_score值(它在类和相同类的对象之间不同)


  • 共2个答案

    匿名用户

    并不是抽象类的所有成员函数都需要是纯虚拟的(只要至少有一个是)。 您的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()将在抽象类中实现,所有派生的类都可以使用。