学习这篇知识之前可以先看看c++类的对象与使用、类的构造函数、类的组合
前向引用声明
我们知道,C++的类跟函数一样,应当先定义然后再使用。
但是在处理类的组合的时候,经常会遇到两个类互相引用的情况——这种“圆环套圆环”的情况,称为互相依赖。
比如说:
class A
{
public:
void function(B b);
};
class B
{
public:
void function2(A a);
};
这里类A的成员函数function使用的形式参数是类B的对象,而类B的成员函数function2使用的形式参数是类A的对象
这样就造成了一个悖论:不管把哪个类放在前面,结果都会导致编译错误。要解决这种问题,可以使用前向引用声明。
前向引用声明,指的是在引用未定义的类之前,首先把这个类的名字告诉编译器——这样编译器遇到标识符的时候,就知道那是一个类名,不会引发编译错误——而类的完整定义可以放在程序的其他地方。
在上述程序加上前向引用声明,问题就解决了:
class B;
class A
{
public:
void function(B b);
};
class B
{
public:
void function2(A a);
};
需要注意的是,尽管使用了前向引用声明,但是在提供了一个完整的类定义之前,不能定义该类的对象,也不能在成员函数中使用该对象。例如:
class Elder;
class Toad
{
Elder h; //错误:类Elder的定义不完善
};
class Elder
{
Toad h;
};
这个时候,可以声明前向引用声明类的引用或者指针,这样就不会发生编译错误了。
class Elder;
class Toad
{
Elder &h;
};
class Elder
{
Toad &h;
};
注意,即使是声明了引用,仍然不能在类内的方法定义中直接调用定义不完善的类的方法:
class E1der;
class Toad
{
private:
Elder &h;
public:
void setweather()
{
h.sunny(); //不合法,因为此时h尚未定义完善
}
};
为此,可以等到要调用的方法所在类定义完善之后,再在类外定义类的方法。
结构体
结构体是一种特殊形态的类——它和类的使用方法几乎完全一样。
唯一的区别在于:在类中,如果直接定义成员类型,不写访问控制属性,比如这样:
class A
{
int a,b;
};
那么,成员变量a,b将会默认设置为私有成员。而结构体则相反:
struct A
{
int a,b;
};
成员变量a,b默认会被设置为公有成员。
可能会问明明已经有类(class)了,还需要结构体做什么呢?
实际上,C++语言的结构体本来就是从C语言中继承得到的
C语言中只有结构体,没有类,不允许定义结构体的函数成员,而且没有访问控制的概念。
C语言是一种典型的面向过程的语言,它的结构体完全是为面向过程的程序服务的,并不能满足面向对象程序设计的要求。
为了保持对C语言的向下兼容,C++语言仍然保留了struct关键字,但是另外引入了class作为定义类的首选关键字。