[关闭]
@skyway 2015-04-21T14:12:06.000000Z 字数 3782 阅读 911

Effective C++笔记——31文件编译依存关系

C++


降低依存关系

  1. #include <string>
  2. #include <memory> //STL不应当用于前置声明。此声明用于智能指针
  3. class PersonImpl; //Person的实现类的前置声明
  4. class Date;
  5. class Address;
  6. class Person{
  7. public:
  8. Person(const std::string& name, const Date& birthday, const Address& addr);
  9. std::string name() const;
  10. std::string birtyday() const;
  11. std::string address() const;
  12. ...
  13. private:
  14. std::tr1::shared_ptr<PersonImpl> pImpl; //智能指针指向实现物
  1. #include "datefwd.h" //该头文件内声明但未定义Date类,这样就不需要做前置声明了
  2. Date today();
  3. void clearAppointments(Date d);
  1. //string是个typedef:basic_string<char>,该前置声明并不正确,事实上对STL中的类做前置声明也没有必 要,直接包含就可以了
  2. namespace std{
  3. class string;
  4. }
  5. class Date;
  6. class Address;
  7. class Person{
  8. ...
  9. };

实现方式

Handle classes(pimpl idiom,转交给相应的实现类,入PersonImpl类)

  1. //////////////////////////////////////////////////////////////////
  2. //person.h
  3. #include <string>
  4. #include <memory>
  5. class PersonImpl;
  6. class Person{
  7. public:
  8. Person(const std::string& name, const std::string& birthday,const std::string& addr);
  9. std::string getname()const;
  10. std::string birthDate() const;
  11. std::string address()const;
  12. private:
  13. std::tr1::shared_ptr<PersonImpl> pImpl; //指向实现物的指针
  14. };
  15. ////////////////////////////////////////////////////////////
  16. //person.cpp
  17. #include "stdafx.h"
  18. #include "Person.h"
  19. #include "PersonImpl.h"
  20. Person::Person(const std::string& name, const std::string& birthday,const std::string& addr)
  21. :pImpl(new PersonImpl(name,birthday,addr))
  22. {}
  23. std::string Person::getname() const
  24. {
  25. return pImpl->getname();
  26. }
  27. std::string Person::birthDate() const
  28. {
  29. return pImpl->birthDate();
  30. }
  31. std::string Person::address()const
  32. {
  33. return pImpl->address();
  34. }
  35. ///////////////////////////////////////////////////////////////
  36. //personImpl.h
  37. #include <string>
  38. class PersonImpl{
  39. public:
  40. PersonImpl(const std::string& name, const std::string& birthday, const std::string& addr)
  41. :mName(name),mBirthday(birthday),mAddr(addr){}
  42. std::string getname()const;
  43. std::string birthDate() const;
  44. std::string address()const;
  45. private:
  46. std::string mName;
  47. std::string mBirthday;
  48. std::string mAddr;
  49. };
  50. ////////////////////////////////////////////////////////////////////
  51. //personImpl.cpp
  52. #include "stdafx.h"
  53. #include "PersonImpl.h"
  54. std::string PersonImpl::getname() const
  55. {
  56. return mName;
  57. }
  58. std::string PersonImpl::birthDate() const
  59. {
  60. return mBirthday;
  61. }
  62. std::string PersonImpl::address()const
  63. {
  64. return mAddr;
  65. }
  66. //main.cpp
  67. #include "stdafx.h"
  68. #include "person.h"
  69. int _tmain(int argc, _TCHAR* argv[])
  70. {
  71. std::string lname = "name";
  72. std::string lDate = "1990";
  73. std::string lAddr = "beijing";
  74. class Person lper(lname,lDate,lAddr);
  75. return 0;
  76. }

abstract base class(interface class)

抽象基类,即接口类,这种类的目的是描述派生类的接口,通常不含有成员变量,也没有构造函数,只有一个虚析构函数以及一组纯虚函数,用来描述整个接口。可以将Person类写成这种接口类:

  1. class Person{
  2. public:
  3. virtual ~Person();
  4. virtual std::string name() const = 0;
  5. virtual std::string birtyday() const = 0;
  6. virtual std::string address() const = 0;
  7. ...
  8. static std::tr1::shared_ptr<Person> create(const std::string& name, const Date& birthday, const Address& addr); //返回指针指向一个动态分配的Person“对象”,避免忘记delete
  9. };

除非接口类的接口被修改,否则不需要重新编译。使用接口类时用引用或指针编写程序,通常的手段是使用工厂函数或虚构造函数,返回指向该类型的指针(或更为可取的智能指针)。

  1. std::tr1::shared_ptr<Person> pp(Person::create(name, dateOfBirth, address)); //创建对象。注意静态函数的用法

完整例子:

  1. class AClass: public AClassFactory {
  2. public :
  3. AClass() {}
  4. void interface_1();
  5. std:: string interface_2();
  6. virtual ~ AClass();
  7. // ..
  8. }
  9. class AClassFactory {
  10. public :
  11. virtual void interface_1() = 0 ;
  12. virtual std:: string interface_2() = 0 ;
  13. // ..
  14. virtual ~ AClassFactory() { /* .. */ }
  15. static std::tr1::shared_ptr < AClassFactory > Produce( /* .. */ )
  16. {
  17. // this factory function could be more complicated in practice..
  18. return std::tr1::shared_ptr < AClassFactory > ( new AClass);
  19. }
  20. // ..
  21. }
  22. // AClassFactory could be used in this way..
  23. std::tr1::shared_ptr < AClassFactory > pAClassObject;
  24. pAClassObject = AClassFactory::Produce( /* .. */ );
  25. // pAClassObject->..

摘抄自:
http://blog.csdn.net/banguijun/article/details/7880485
http://www.cppblog.com/note-of-justin/archive/2012/10/02/105784.html
http://m.blog.csdn.net/blog/liyun123gx/25979259

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注