c++中的前置声明
2013-07-19 15:40 清心朗静 阅读(2360) 评论(0) 编辑 收藏 举报引用google c++编码规范:
When you include a header file you introduce a dependency that will cause your code to be recompiled whenever
the header file changes. If your header file includes other header files, any change to those files will cause any code
that includes your header to be recompiled. Therefore, we prefer to minimize includes, particularly includes of header
files in other header files.
include一个头文件,就多了一种依赖,当头文件发生变化时,需要重新编译,因此尽量少用include,尤其是在头文件中包含头文件的情况下。
前置声明:减少include;解决循环依赖的问题。
如下,两个类中互包含了类对象成员,产生循环依赖。
class Barney{ Fred x; };
class Fred{ Barney y;};
在使用一个类之前,必须先定义该类。使用前置声明,在引用未定义的类之前,将该类的名字告诉编译器,使编译器知道那是一个类名。
注意:提供完整类定义之前,不能定义该类的对象,也不能在内联成员函数中使用该类的对象。
前置声明使用错误情况1、
class Fred;
class Barney{ Fred x; //error C2079: “Barney::x”使用未定义的 class“Fred” };
class Fred { Barney y; };
前置声明使用错误情况2、
class Fred;
class Barney
{
public: void method(){ x->dosomething(); //error C2227: “->dosomething”的左边必须指向类/结构/联合/泛型类型 }
private: Fred *x;
};
class Fred
{
public: void dosomething(){};
private: Barney *y;
};
解决的办法:
修改两个类的定义顺序,或者将method改为非内联函数。
class Fred;
class Barney
{
public: void method();
private: Fred *x;
};
class Fred
{
public: void dosomething(){};
private: Barney *y;
};
//改成非内联函数,在Fred完整定义后在给出函数定义,或者更改两个类定义的顺序。
void Barney::method() { x->dosomething(); }
综上,使用前置声明可以解决循环包含的部分问题。另外要避免互相定义使用类对象的情况。
google编码规范在头文件中使用前置声明的注意事项:
How can we use a class Foo in a header file without access to its definition?
- We can declare data members of type Foo* or Foo&.
- We can declare (but not define) functions with arguments, and/or return values, of type Foo. (One exception is if an argument Foo or const Foo& has a non-explicit, one-argument constructor, in which case we need the full definition to support automatic type conversion.)
- We can declare static data members of type Foo. This is because static data members are defined outsidethe class definition.
摘自c++ primer:
class Screen;
前置声明,也称前向声明(forward declaration)。在声明之后,定义之前,类Screen是个不完整类型(incomplete type),即已知Screen是一个类型,但是不知道包含哪些成员。
不完全类型只能以有限方式使用。不能定义该类型的对象。不完全类型只能用于定义指向该类型的指针及引用,或者用于声明(而不是定义)使用该类型作为形参类型或返回类型的函数。
关键,区分下声明和定义。