图一所示,Manager类重复继承了Person类的信息,这增加了Manager类在数据一致性维护上的系统开销。图二所示,使用虚基类避免了数据冗余。根据图二编程实现Manager类对象的创建和撤销,并考察在此过程中各类构造函数和析构函数的调用顺序。
#include <iostream>
#include <string>
#define output() \
do \
{ \
std::cout << __PRETTY_FUNCTION__ << '\n'; \
} while (0)
class Person
{
public:
Person() { output(); }
virtual ~Person() { output(); }
private:
std::string _name;
int _id;
std::string _tel;
};
class Stuff1 : public Person
{
public:
Stuff1() { output(); }
virtual ~Stuff1() { output(); }
private:
std::string _post;
};
class Technician1 : public Person
{
public:
Technician1() { output(); }
virtual ~Technician1() { output(); }
private:
std::string _major;
};
class Manager1 : public Stuff1, public Technician1
{
public:
Manager1() { output(); }
virtual ~Manager1() { output(); }
};
class Stuff2 : virtual public Person
{
public:
Stuff2() { output(); }
virtual ~Stuff2() { output(); }
private:
std::string _post;
};
class Technician2 : virtual public Person
{
public:
Technician2() { output(); }
virtual ~Technician2() { output(); }
private:
std::string _major;
};
class Manager2 : public Stuff2, public Technician2
{
public:
Manager2() { output(); }
virtual ~Manager2() { output(); }
};
int main()
{
{
std::cout << "The invoke order of constructors and destructors for class Manager1:\n";
Manager1 m;
}
{
std::cout << "The invoke order of constructors and destructors for class Manager2:\n";
Manager2 m;
}
return 0;
}
编译运行输出
$ g++ -Wall main.cpp -o main
$ ./main
The invoke order of constructors and destructors for class Manager1:
Person::Person()
Stuff1::Stuff1()
Person::Person()
Technician1::Technician1()
Manager1::Manager1()
virtual Manager1::~Manager1()
virtual Technician1::~Technician1()
virtual Person::~Person()
virtual Stuff1::~Stuff1()
virtual Person::~Person()
The invoke order of constructors and destructors for class Manager2:
Person::Person()
Stuff2::Stuff2()
Technician2::Technician2()
Manager2::Manager2()
virtual Manager2::~Manager2()
virtual Technician2::~Technician2()
virtual Stuff2::~Stuff2()
virtual Person::~Person()