An abstract class declares an interface that derived classes must implement.

Abstract Classes

abstract_classes.cpp
#include <iostream>
#include <string>

class Task {
public:
    virtual std::string label() = 0;
    virtual int effort() = 0;
};

class EmailTask : public Task {
private:
    int messages;

public:
    EmailTask(int count) {
        messages = count;
    }

    std::string label() override {
        return "email";
    }

    int effort() override {
        return messages * 2;
    }
};

class BuildTask : public Task {
private:
    int files;

public:
    BuildTask(int count) {
        files = count;
    }

    std::string label() override {
        return "build";
    }

    int effort() override {
        return files * 3;
    }
};

int main() {
    bool useBuild = ;
    int count = ;

    EmailTask email(count);
    BuildTask build(count);
    Task* task = &email;

    if (useBuild) {
        task = &build;
    }

    std::cout << "task=" << task->label() << std::endl;
    std::cout << "effort=" << task->effort() << std::endl;
    return 0;
}
#include <iostream>
#include <string>

class Task {
public:
    virtual std::string label() = 0;
    virtual int effort() = 0;
};

class EmailTask : public Task {
private:
    int messages;

public:
    EmailTask(int count) {
        messages = count;
    }

    std::string label() override {
        return "email";
    }

    int effort() override {
        return messages * 2;
    }
};

class BuildTask : public Task {
private:
    int files;

public:
    BuildTask(int count) {
        files = count;
    }

    std::string label() override {
        return "build";
    }

    int effort() override {
        return files * 3;
    }
};

int main() {
    bool useBuild = ;
    int count = ;

    EmailTask email(count);
    BuildTask build(count);
    Task* task = &email;

    if (useBuild) {
        task = &build;
    }

    std::cout << "task=" << task->label() << std::endl;
    std::cout << "effort=" << task->effort() << std::endl;
    return 0;
}
#include <iostream>
#include <string>

class Task {
public:
    virtual std::string label() = 0;
    virtual int effort() = 0;
};

class EmailTask : public Task {
private:
    int messages;

public:
    EmailTask(int count) {
        messages = count;
    }

    std::string label() override {
        return "email";
    }

    int effort() override {
        return messages * 2;
    }
};

class BuildTask : public Task {
private:
    int files;

public:
    BuildTask(int count) {
        files = count;
    }

    std::string label() override {
        return "build";
    }

    int effort() override {
        return files * 3;
    }
};

int main() {
    bool useBuild = ;
    int count = ;

    EmailTask email(count);
    BuildTask build(count);
    Task* task = &email;

    if (useBuild) {
        task = &build;
    }

    std::cout << "task=" << task->label() << std::endl;
    std::cout << "effort=" << task->effort() << std::endl;
    return 0;
}
#include <iostream>
#include <string>

class Task {
public:
    virtual std::string label() = 0;
    virtual int effort() = 0;
};

class EmailTask : public Task {
private:
    int messages;

public:
    EmailTask(int count) {
        messages = count;
    }

    std::string label() override {
        return "email";
    }

    int effort() override {
        return messages * 2;
    }
};

class BuildTask : public Task {
private:
    int files;

public:
    BuildTask(int count) {
        files = count;
    }

    std::string label() override {
        return "build";
    }

    int effort() override {
        return files * 3;
    }
};

int main() {
    bool useBuild = ;
    int count = ;

    EmailTask email(count);
    BuildTask build(count);
    Task* task = &email;

    if (useBuild) {
        task = &build;
    }

    std::cout << "task=" << task->label() << std::endl;
    std::cout << "effort=" << task->effort() << std::endl;
    return 0;
}
#include <iostream>
#include <string>

class Task {
public:
    virtual std::string label() = 0;
    virtual int effort() = 0;
};

class EmailTask : public Task {
private:
    int messages;

public:
    EmailTask(int count) {
        messages = count;
    }

    std::string label() override {
        return "email";
    }

    int effort() override {
        return messages * 2;
    }
};

class BuildTask : public Task {
private:
    int files;

public:
    BuildTask(int count) {
        files = count;
    }

    std::string label() override {
        return "build";
    }

    int effort() override {
        return files * 3;
    }
};

int main() {
    bool useBuild = ;
    int count = ;

    EmailTask email(count);
    BuildTask build(count);
    Task* task = &email;

    if (useBuild) {
        task = &build;
    }

    std::cout << "task=" << task->label() << std::endl;
    std::cout << "effort=" << task->effort() << std::endl;
    return 0;
}
#include <iostream>
#include <string>

class Task {
public:
    virtual std::string label() = 0;
    virtual int effort() = 0;
};

class EmailTask : public Task {
private:
    int messages;

public:
    EmailTask(int count) {
        messages = count;
    }

    std::string label() override {
        return "email";
    }

    int effort() override {
        return messages * 2;
    }
};

class BuildTask : public Task {
private:
    int files;

public:
    BuildTask(int count) {
        files = count;
    }

    std::string label() override {
        return "build";
    }

    int effort() override {
        return files * 3;
    }
};

int main() {
    bool useBuild = ;
    int count = ;

    EmailTask email(count);
    BuildTask build(count);
    Task* task = &email;

    if (useBuild) {
        task = &build;
    }

    std::cout << "task=" << task->label() << std::endl;
    std::cout << "effort=" << task->effort() << std::endl;
    return 0;
}
pure virtual A pure virtual function, written with `= 0`, makes a class abstract.