这个在设计模式专栏总结过,这里也是一个意思,具体参考文章。
这个方法就是利用纯虚函数来规定接口,具体如下:
//person.h
#ifndef PERSON_H_
#define PERSON_H_
#include
#include
#include
using namespace std;
class Person
{
public:
Person() {};
virtual ~Person() {};
virtual string name() const = 0;
static shared_ptr<Person> create(const string& name);
};
#endif
首先定好接口,然后指定为虚函数。
//person.cc
#include "person.h"
#include "personimpl.h"
shared_ptr<Person> Person::create(const string& name)
{
return shared_ptr<Person> (new RealPerson(name));
}
接下来是personimpl.h 和personimpl.cc
//personimpl.h
#include "person.h"
class RealPerson: public Person
{
public:
RealPerson(const string name):m_name(name){};
string name() const {cout<<m_name<<endl;};
virtual ~RealPerson() {};
private:
string m_name;
};
//personimpl.cc
#include "personimpl.h"
RealPerson(const string name):m_name(name){};
string name() const
{
cout<<m_name<<endl;
return m_name;
};
接下的main函数只要依赖接口person.h就行了.
#include "person.h"
int main()
{
string name = "eng";
shared_ptr<Person> p = Person::create(name);
p->name();
}
这里可以看到main.cc 依赖person.h, 至于personimpl.h的成员变量(实现),personimpl.cc怎么改成员函数,编译的时候都不会影响main.cc, 因为没有依赖关系。
在做测试的遇到一个问题,就是抽象类,析构函数要么不申明(编译器自己生成),如果申明的话一定要给一个定义,纯虚函数直接=0就行,不用再给定义。如果自己手欠写了构造函数,也要给一个定义,所以总结下来:对于基类中的函数,编译器考虑到后面继承类可能会用,所以必须给一个定义,哪怕是空的。