问题描述:
Person.h
#include <string>
#include "Date.h"
class Person
{
public:
Person(const std::string& name,const Date& birthday);
std::string name() const;
std::string birthDate() const;
std::string address() const;
private:
...
};
Person.cpp
#include "Person.h"
Person::Person(const std::string& name,const Date& birthday)
{
}
Date.h
class Date
{
public:
Date(int year,int month,int day);
~Date(void);
};
Person.h中包含了Date.h,如果Date.h被改变,那么不仅Date.cpp、Person.cpp也会被编译。
解决办法:用“声明依存性”代替“定义依存性”。
将Person.h作如下修改:
class Date;
class Person
{
public:
Person(const std::string& name,const Date& birthday);
std::string name() const;
std::string birthDate() const;
std::string address() const;
};
说明:
由于编译器必须在编译期间知道对象的大小,所以使用声明式时,无法使用该类的对象。
注意:当你声明一个函数而它用到某个class时,你并不需要该class的定义:纵使函数以by value方式传递类型的参数(或返回值)亦然
例如:
class Date; //class声明式
Date today() //正确,虽然返回值是Date的定义式
void clearAppointments(Date d); // Date的定义式
两种设计思路
1. Handle class方式
Person.h
class PersonImpl;
class Date;
class Person
{
public:
Person(const std::string& name,const Date& birthday);
std::string name() const;
std::string birthDate() const;
std::string address() const;
private:
std::tr1::shared_ptr<PersonImpl> pImpl;
};
Person.cpp
#include "Person.h" //我们正在实现Person class,
//所以必须#include 其定义式
#include "PersonImpl.h"
Person::Person(const std::string& name,const Date& birthday) :
pImpl(new PersionImpl(name,birthday))
{}
std::string Person::name() const
{
return pImpl->name();
}
2. Interface class
class Person{
public:
static std::tr1::shared_ptr<Person> create(const std::string& name,
const Date& birthday);
virtual ~Person();
virtual std::string name() const = 0;
virtual std::string birthDate() const = 0;
virtual std::string address() const = 0;
...
};
实现类
class RealPerson: public Person{
public:
RealPerson(const std::string& name,const Date& birthday) :
theName(name),theBirthDate(birthday){}
virtual ~RealPerson() {}
std::string name() const;
std:: string birthDate() const;
private:
std::string theName;
Date theBirthDate;
};
Person.cpp
std::tr1::shared_ptr<Person> Person::create(const std::string& name,
const Date& birthday)
{
return std::tr1::shared_ptr<Person>(new RealPerson(name,birthday));
}