抽象基类或派生类中的类变量?

时间:2017-09-05 13:05:27

标签: c++ oop inheritance

我有一个抽象类,其变量owner_是一个字符串。每个派生类都声明此变量的名称。将变量放在抽象基类中是更好的做法,还是可以在派生类中多次实现它?

#include <string>
#include <iostream>

class Pet
{
    public:
        Pet(const std::string& owner) : owner_(owner) {}
        virtual ~Pet() = 0;
        virtual void print_status() = 0;
    protected:
        const std::string owner_;
};

Pet::~Pet() {}

class Dog : public Pet
{
    public:
        Dog(const std::string& owner) : Pet(owner) {}
        ~Dog() {};
        void print_status()
        {
            std::string s = "Woof! My owner is ";
            s += owner_;
            std::cout << s << std::endl;
        }
    // Or better here?
    // private:
    //     const std::string owner_;
};

class Cat : public Pet
{
    public:
        Cat(const std::string& owner) : Pet(owner) {}
        ~Cat() {};
        void print_status()
        {
            std::string s = "Meow! My owner is ";
            s += owner_;
            std::cout << s << std::endl;
        }
    // Or better here?
    // private:
    //     const std::string owner_;
};

int main()
{
    Dog dog("Mario");
    dog.print_status();

    Cat cat("Luigi");
    cat.print_status();

    return 0;
}

2 个答案:

答案 0 :(得分:4)

IMO正是抽象基类的用途:为继承层次结构中的接口提供通用实现 我只是更进一步,甚至将接口与抽象基类分开:

struct IPet {
    virtual ~IPet() = {}
    virtual void print_status() = 0;
    virtual const std::string& get_owner() const = 0;
};

class Pet : public IPet
{
public:
    Pet(const std::string& owner) : owner_(owner) {}
    virtual const std::string& get_owner() const { return owner_; }
    virtual ~Pet() {} // = 0; Don't declare the destructor as pure virtual function
    virtual void print_status() = 0;
protected:
    std::string owner_;
};

答案 1 :(得分:1)

您可能希望使用abstract来强制子类实现该方法,但不一定要在其中定义任何内容。如果您故意使用它们,那么将所有者置于基类中,但各个方法中的不同内容是正确的。

例如,如果您希望所有子类至少在自己的类中声明函数(有时需要相应子类的不同行为),则使用抽象方法。

class Pet
{
public:
    Pet(const std::string& owner) :
        owner_(owner) {}
    virtual ~Pet() = 0;
    virtual void print_status() = 0;
protected:
    const std::string owner_;
};

Pet::~Pet() {}

class Dog : public Pet
{
private:
    int age;
public:
    Dog(const std::string& owner, int age) :
        Pet(owner), age(age) {}
    ~Dog() {};
    void print_status(){
        std::cout << "Woof! My owner is " << this->owner_ << 
            " and my age is " << this->age << "\n\n";
    }
};

class Cat : public Pet
{
public:
    Cat(const std::string& owner) :
        Pet(owner) {}
    ~Cat() {};
    void print_status() {
        std::cout << "Miaw, my owner is " << this->owner_ << '\n';
    }
};

int main()
{
    Dog dog("Mario", 25);
    dog.print_status();

    Cat cat("Luigi");
    cat.print_status();

    system("pause");
    return 0;
}