Visual Studio 编译 C++ 遇到大量标识符未定义、缺失 ; 问题的解决方案

项目场景:

使用 Visual Studio 尝试在 VTM-6.0 的 VLCWriter.cpp 和 VLCReader.cpp 中调用自定义函数,自定义函数的声明的定义均在自己写的文件 HomoTransform.h, HomoTransform.cpp


问题描述

由于需在 VLCWriter.cppVLCReader.cpp 中调用到 HomoTransform.cpp 中的函数,所以须在 VLCReader.cpp 中引用头文件 HomoTRanshform.h,当时没注意,没在 VLCReader.cpp 中去引用,而是在 VLCReader.cpp 引用的 Slice.h 中去引用了,导致了发生了循环引用的问题,编译时报出大量 cxxxx cxxx 错误,即 标识符未定义缺少“;” 的错误

Visual Studio 编译 C++ 遇到大量标识符未定义、缺失 ; 问题的解决方案_第1张图片


原因分析:

问题原因是发生了循环引用,会导致某些头文件受单次引用的限制可能不会正确展开,导致一些定义缺失
基本的思路是这样的:[代码来源 https://blog.csdn.net/centurionAX/article/details/107984778]

//错误示范
//Parent.h
#pragma once

#include "Child.h"

class Parent
{
public:
	Parent();
	void update();
	void foo();

private:
	Child* mChild;
};

//Parent.cpp
#include "Parent.h"

Parent::Parent() : mChild(nullptr)
{
	mChild = new Child();
}

void Parent::foo()
{
	//do something
}

void Parent::update()
{
	mChild->update(this);
}

//Child.h
#pragma once

#include "Parent.h"

class Child
{
public:
	void update(Parent*);
};

//Child.cpp
#include "Child.h"

void Child::update(Parent* parent)
{
	//do something
    if (/*some condition triggered*/)
    {
        parent->foo();
    }
}

编译 Child.cpp 时,编译器遇到 #include "Child.h" 就会把 Child. h 中的内容复制、粘贴到 Child.cpp 对应位置中,即展开;
展开 Child. h 时遇到了 #include "Parent.h" 于是把 "Parent.h" 展开
展开 "Parent.h" 时又遇到了 #include "Child.h",但是由于之前已经展开过了 Child. h ,受#pragma once 限制不会重复展开,从而导致这时的 "Parent.h" 找不到了类 Child 的定义


解决方案:

#include 指令放在 .cpp 中,并在 Parent.h 中写一个 Child 的预定义
[代码来源 https://blog.csdn.net/centurionAX/article/details/107984778]

//正确示范
//Parent.h
#pragma once

class Child; //这里发生了改变

class Parent
{
public:
   Parent();
   void update();
   void foo();

private:
   Child* mChild;
};

//Parent.cpp
#include "Parent.h"
#include "Child.h" //将头文件的include放在cpp文件里

Parent::Parent() : mChild(nullptr)
{
   mChild = new Child();
}

void Parent::foo()
{
   //do something
}

void Parent::update()
{
   mChild->update(this);
}

//Child.h
#pragma once

class Parent; //这里发生了改变

class Child
{
public:
   void update(Parent*);
};

//Child.cpp
#include "Child.h"
#include "Parent.h" //将头文件的include放在cpp文件里

void Child::update(Parent* parent)
{
   //do something
   if (/*some condition triggered*/)
   {
       parent->foo();
   }
}

你可能感兴趣的:(Bug,集锦,c++,visual,studio)