# 前向声明

# 函数的声明

我们知道对与函数可以先声明后定义,如下代码可以正常工作

#include <iostream>
#include <vector>

void printVector(std::vector<int>& v);

int main(int argc, char** argv)
{
    std::vector<int> vv{10, 100};
    printVector(vv);
    return 0;
}

void printVector(std::vector<int>& v)
{
    for(auto &val : v) {
        std::cout << val << " ";
    }
    std::cout << std::endl;
}

# 类的前向声明

对于类来说,类似的,同样可以先声明,同时使用声明的类来声明变量。

#include <memory>

class A;

class B {
    public:

        std::shared_ptr<A> ptr = nullptr;
        
        void printA(const A a);
};

class A {
    public:
        int v = 10;

};

void B::printA(const A a)
{
    std::cout << a.v << std::endl;
}

int main(int argc, char **argv)
{
    B b;
    A a;
    b.printA(a);
    return 0;
}

如上,先声明了类A,并使用类A做为B指针数据成员的类型和B成员函数的形参类型。

但如下代码,这样

#include <memory>

class A;

class B {
    public:
        void printA(const A a);
};

void B::printA(const A a) //  error
{
    std::cout << a.v << std::endl;
}

class A {
    public:
        int v = 10;

};

int main(int argc, char **argv)
{
    B b;
    A a;
    b.printA(a);
    return 0;
}

或者这样:

#include <memory>

class A;

class B {
    public:

        A a1;

        void printA(const A a);
};

class A {
    public:
        int v = 10;

};

void B::printA(const A a)
{
    std::cout << a.v << std::endl;
}


int main(int argc, char **argv)
{
    B b;
    A a;
    b.printA(a);
    return 0;
}

再或者这样:

#include <memory>

class A;

class B {
    public:
        B(){
            int i = a2->v;
        }

        A *a1;
        A *a2;
        void printA(const A a);
};

class A {
    public:
        int v = 10;

};

void B::printA(const A a)
{
    std::cout << a.v << std::endl;
}


int main(int argc, char **argv)
{
    B b;
    A a;
    b.printA(a);
    return 0;
}

以上几种情况都会报如下错误:

error: invalid use of incomplete type ‘class A’

原因是,前向声明只是声明了类,并没有定义类的成员,还没有给类分配存储空间,因此只能使用前向声明的类声明变量,声明指针,做函数的形参,不能在定义之前用来定义变量,不能在定义之前访问类中的成员变量或函数。

# Reference