Effective C++ 条约31:将文件间的编译依存关系降至最低

Effective C++ 条款31:将文件间的编译依存关系降至最低
原文:
假设你对C++程序的某个class实现文件做了轻微的修改。注意,修改的不是class接口,而是实现,而且只改了private成分。然后重新建置这个程序,并预计只花数秒就好了。...然后大吃一惊,然后感到困惑,因为你意识到整个世界都被重新编译和链接了!当发生这种事情,你不气恼吗?


为了重现作者描述的情况,我做了如下实验:


main.cc   Person.h Person.cc  RealPerson.h  RealPerson.cc 

main.cc
#include <memory>

#include "Person.h"

using namespace std;

int main()
{

  Person p("p1");

  p.Print();
  
  return 0;
}


Person.h
#ifndef PERSON_H_
#define PERSON_H_

#include <string>

#include "RealPerson.h"

using namespace std;

class Person
{
public:
  Person(const string &_name);
  void Print();

private:
  RealPerson p;
};

#endif

Person.cc
#include "Person.h"

Person::Person(const string &_name) : p(RealPerson(_name))
{
}

void
Person::Print()
{
  p.Print();

  RealPerson rp("RealPersonName");
  rp.Print();
}

RealPerson.h
#ifndef REAL_PERSON1_H_
#define REAL_PERSON1_H_

#include <iostream>

#include <string>

using namespace std;

class RealPerson
{
public:
RealPerson(const string &_name) : name (_name) {}

  void Print();

private:
  string name;
};


#endif

RealPerson.cc
#include "RealPerson.h"

void
RealPerson::Print()
{
  cout << "RealPerson::Print()::name=" << name << endl;
}


Makefile
#
# author: zhaokai
# date: 2013-11-28
#

CURRENT_DIR=.
CXXFLAGS += -g -std=c++11 -Wall -Wextra 

TESTS = main

SOURCE_FILES=\
$(wildcard $(CURRENT_DIR)/*.cc)

OBJ_FILES=\
$(patsubst %.cc, %.o, $(SOURCE_FILES))

all : $(TESTS)

clean :
rm -f $(TESTS)
rm -f $(OBJ_FILES)

$(CURRENT_DIR)/%.o : $(CURRENT_DIR)/%.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(CPPLIB)  -c $< -o $@

$(TESTS) : $(OBJ_FILES) 
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(CPPLIB) $^ -o $@


问题描述:
我修改RealPerson中的Print方法,那么RealPerson.o肯定是要编译的,但是Person.o文件是否需要重新编译呢?

我的实验结果:
   RealPerson.o重新编译,Person.o没有重新编译,执行文件重新编译,并且执行的结果是RealPerson修改后的正确结果。

不知道为什么改了RealPerson,而依赖它的Person文件却没有重新编译!

------解决方案--------------------
又见到了makefile,我考Unix的时候差点挂掉Effective C++ 条约31:将文件间的编译依存关系降至最低
看着就伤心