首页 > 解决方案 > C++ 打印与死亡钻石

问题描述

首先让我解释一下我的层次结构:

        Person
       /     \
   Student Employee
       \     /
       Intern

每个类都有output自己的函数,打印它们的数据成员,我只需要打印Person一次。问题是StudentandEmployee不是抽象类,而且人们也会制作他们类型的对象,所以我不能只在Intern级别上调用输出函数。

正如您将在下面的代码中看到的那样,我已经设法解决了这个问题,但我认为这很丑陋而且不是很多态。我创建了一个额外的输出函数,因此它适用于所有情况。有没有更好的方法来实现这一点?

class Person {
    string name;
    int id;
public:
        virtual void output(ostream& out) {
        out << name << "," << id;
    }
}

学生:

class Student : virtual public Person {
    string major;
    int year;
public:
    virtual void output(ostream& out) {
        Person::output(out);
        out << "," << major << "," << year;
    }
    virtual void outputStudOnly(ostream& out) {
        out << "," << major << "," << year;
    }
};

员工:

class Employee : virtual public Person{
    string jobTitle;
public:
    virtual void output(ostream& out) {
        Person::output(out);
        out << "," << jobTitle;
    }
    virtual void outputEmpOnly(ostream& out) {
        out << "," << jobTitle;
    }
};

和实习生:

class Intern : public Student, public Employee {
public:
    virtual void output(ostream& out) {
        Person::output(out);
        Student::outputStudOnly(out);
        Employee::outputEmpOnly(out);
    }
};

标签: c++ooppolymorphismdiamond-problem

解决方案


那是什么模板方法。以下是我将如何编写此代码:

class Person {
    string name;
    int id;
public:
        void output(ostream& out) {
        out << name << "," << id;
        output_impl(out);
    }
private:
       virtual void output_impl(ostream& ) {}
};

class Student : virtual public Person {
    string major;
    int year;
private:
    virtual void output_impl(ostream& out) {
        out << "," << major << "," << year;
    }

};

class Employee : virtual public Person {
    string jobTitle;
private:
    virtual void output_impl(ostream& out) {
        out << "," << jobTitle;
    }
};

class Intern : public Student, public Employee {
private:
    virtual void output_impl(ostream& out) {
        Student::output_impl(out);
        Employee::output_impl(out);
    }
};

而不是你调用output的对象。


推荐阅读