在C#或Java中,类是同时声明和定义的.在C++中,规范是分开执行.如果我们将整个类写在一个文件中,例如.cpp文件并将其包含在引用它的文件中,除了延长编译过程之外,技术上会发生什么样的坏事呢?
Bil*_*ill 12
如果您的实现MyClass都在头文件中,MyClass.h则MyClass只要有人包含,您将需要包含您需要实现的任何文件MyClass.h.
如果你改变任何部分MyClass.h,即使它是微不足道的(例如添加注释甚至是空格),那么包含它的所有文件都必须重新编译,即使接口没有改变.
无论这些问题的玩具项目,但正如你提到的,当你有一个程序,包括类文件的数百(或数千等),仅增加编译时间很划算从接口分离出来实现.
例如,如果我有以下内容:
// MyClass.h
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include "Inventory.h"
class MyClass
{
public:
MyClass();
void processInventory(Inventory& inventory)
{
// Do something with each item in the inventory here
// that uses iostream, iomanip, sstream, and string
}
private:
// ...
};
Run Code Online (Sandbox Code Playgroud)
它会更加理性地写成:
// MyClass.h
class Inventory;
class MyClass
{
public:
MyClass();
void processInventory(Inventory& inventory);
private:
// ...
};
// MyClass.cc
#include "MyClass.h"
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include "Inventory.h"
MyClass()::MyClass()
{
}
void MyClass()::processInventory(Inventory& inventory)
{
// Do something with each item in the inventory here
// that uses iostream, iomanip, sstream, and string
}
Run Code Online (Sandbox Code Playgroud)
注:包括MyClass.h不等于iostream,iomanip,sstream,string,或Inventory.h不得不进行解析.更改processInventory工作方式并不意味着MyClass.h必须重新编译所有使用的文件.
请注意,MyClass现在弄清楚如何使用它会更容易.头文件有一个重要目的:它们向人们展示如何使用你的课程.通过修改MyClass.h,很容易看到功能列表.如果在标题中定义了每个函数,那么您不能仅查看函数列表.这使得弄清楚如何使用该类更加困难.
您可以打破一个定义规则.
如果你这样写:
class foo
{
public:
void doit();
};
foo::doit() {}
Run Code Online (Sandbox Code Playgroud)
并且在多个类中包含它,您将有多个定义,foo::doit并且您的链接将失败.
但是,如果您将所有类内联,可以通过在类声明中定义它们:
class foo
{
public:
void doit() {
}
};
Run Code Online (Sandbox Code Playgroud)
或者明确地将它们内联:
class foo
{
public:
void doit();
};
inline void foo::doit() {}
Run Code Online (Sandbox Code Playgroud)
那么您可以根据需要多次包含该文件.
| 归档时间: |
|
| 查看次数: |
528 次 |
| 最近记录: |