C ++ notes reduce compilation dependency between header files

Source: Internet
Author: User

1. Compile Dependencies
In some cases, only the private of a class is modified, but a large number of files need to be compiled. The problem is that C ++ does not do a good job of "Separating interfaces from implementations. The class definition not only describes the class interface in detail, but also includes full implementation details. For example:

Class perpson {public: STD: string name () const; STD: String birthdata () const; STD: String address () const ;... PRIVATE: STD: String thename; // Implementation Details: Date thebirthdate; address theaddress ;};

At the top of the person definition file, there may be something like this:

#include <string>#include "date.h"#include "address.h"

Unfortunately, a compilation and storage relationship is formed between the person definition file and Its contained files. If either of these header files is changed or other header files are changed, each file containing the person class must be re-compiled. Such dependencies can cause unspeakable disasters to many projects.
Consider adding a pre-declaration to remove the # include header file:

class Date;class Address;

It is difficult for the compiler to know the object size during compilation. Consider this:

int main(){    int x;    Person p;    ...}

When the compiler sees the definition of X, it knows how much memory must be allocated to hold an int. No problem. Every compiler knows how big an int is. When the compiler sees the definition of P, it also knows that space must be allocated to rotate a person, but how does it know how big a person object is? The only way is to ask the class definition. However, if the class definition can legally not List Implementation Details (using the pre-declaration), how does the compiler know how much space to allocate?

2. Handle class
We can use pimpl to "Hide object implementation details behind a pointer" in the game. We can do this for person: Divide person into two classes, one provides only interfaces, and the other is responsible for implementing this interface. The class to be implemented is named personimpl. The person is defined as follows:

# Include <string> # include <memory> class personimpl; Class date; Class address; class person {public: STD: string name () const ;... PRIVATE: STD: tr1: shared_ptr <personimpl> pimpl; // pointer ,};

The above design is often referred to as pimpl idiom (pimpl is "pointer to implementation"). Classes using pimpl idiom like person are often called handle classes. In this way, the customer of person is completely separated from dates and so on, thus realizing "interface and implementation separation ". The key to this separation is to replace "define dependency" with "declared dependency". In fact, everything comes from these simple design strategies:
1) If you can use object references or object pointers to complete the task, do not use objects.
2) If possible, replace the class definition with the class declaration. Note: When you declare a function and use a class, you do not need the definition of this class. Even if you pass the parameter (or return value) of this type in the by value mode, the same is true:

Class date; // class declarative date today (); // No problem -- the definition of date is not required here. Void clearappointments (date D );

3) provide different header files for declarations and definitions

3. Interface Class
This makes person a special abstract base class called interface class. As follows:

Class person {public: static STD: tr1: shared_ptr <person> Create (); // use a factory method to create a real object virtual ~ Person (); Virtual STD: string name () const = 0; virtual STD: String birthdate () const = 0; virtual STD: String address () const = 0 ;}
class RealPerson: public Person {...}static std::tr1::shared_ptr<Person> create {    return std::tr1::shared_prt<Person>(new RealPerson());}

Note: Put the factory method into a separate factory class, and the effect should be better.

From Objective C ++

PS:Pimpl Implementation Method
Pimpl can be implemented in the following ways:

//Person.h#include <memory>class Person{public:Person(void);~Person(void);private:class PersonImpl;std::tr1::shared_ptr<PersonImpl> pImpl;};//Person.cpp#include "Person.h"class Person::PersonImpl {};Person::Person(void){pImpl = std::tr1::shared_ptr<PersonImpl>(new PersonImpl);}Person::~Person(void){}

The personimpl is defined in the person domain and is invisible to the outside.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.