头文件功能声明问题

时间:2019-04-15 11:40:07

标签: c++

我不知道我在做什么错。

这是我QStack.cpp文件的开始。接下来会出现更多的功能,但是发布的时间会太长。

#include "stdafx.h"
#include "QStack.h"
#include <iostream>
using namespace std;

struct Tstruct {
    int value;
    Tstruct * next;
};

struct TStack {
    int value;
    TStack *next;
};

void StackInit(TStack* *TOP) {
    *TOP = NULL;
};

TStack* Push(TStack *a_top, int a_value) {
    TStack *l_hlp;
    l_hlp = new TStack;
    l_hlp->next = a_top;
    l_hlp->value = a_value;
    return l_hlp;
};

int Pop(TStack* *a_top) {
    TStack *l_hlp;
    int l_val;
    l_hlp = *a_top;     
    *a_top = l_hlp->next;
    l_val = l_hlp->value;
    delete l_hlp;           
    return l_val;
};

接下来,我有一个头文件QStack.h。我不知道它的外观,无论如何我都会遇到一些语法错误...

// QStack.h - Contains declarations of some functions
#pragma once


#ifdef QSTACK_EXPORTS
#define QSTACK_API __declspec(dllexport)
#else
#define QSTACK_API __declspec(dllimport)
#endif
class DLLDIR QStack
{
public:
    TStack* Push(TStack *, int);
    void StackInit(TStack* *);
    int Pop(TStack* *);
    void queueInit(Tstruct * *, Tstruct * *);
    void enqueue(Tstruct * *, Tstruct * *, int);
    int Dequeue(Tstruct* *, Tstruct* *);
};

有人可以提示我在头文件中声明函数的方法吗?另外,我在哪里声明结构类型? 完成后,我应该根据一些教程构建QStack.cpp以获取DLL文件。

4 个答案:

答案 0 :(得分:6)

这里有一个简单的解释,说明编译器在处理代码时的想法,编译器从上至下读取。

因此,如果您执行以下操作:

int var = 0;
StackObject st;

它显示为int,这是什么?一种!我知道这种类型吗?是的,以该语言内置。

StackObject?我想是一种类型,我以前读过它吗?不,错误!

然后要记住两件事:

  1. 声明就足够
  2. 定义足够的地方

如果使用指向类型的指针,则可以进行简单声明。

如果您需要使用该对象(例如使用其data/function/invoking构造函数),则需要一个定义。

例如:

struct declared;
struct defined{};
void f(declared* ptr); // ok
void g(declared copy); // not ok
void w(defined d); // ok
void p(declared* ptr) { ptr->do(); } // not ok

这就是为什么将其放在标题中的原因,这样每个源文件(.cpp)都可以查看对象所需的空间,对象是否具有成员,函数是否具有其他功能。

  • 现在让我们详细了解您的情况:

标头中没有声明任何类型。什么是TStack?什么是Tstruct?什么是DLLDIR

在头文件中,这都不重要,因为头文件未编译。因此,让我们看一下您的源文件。头文件实际上是由预处理器在#include指令的位置复制/粘贴到您的源文件中的。我们看到了什么?在声明它们之前,您仍在类声明中使用这些类型。您必须先声明它们!不允许编译器稍后查看最终声明它们的源文件。

因此,要做的是在头文件中声明要在多个位置使用的所有类型,然后在要使用它们的位置包含这些头文件。因此,为TStack创建一个标题,然后将该标题文件包含在您的QStack.h中。编译时会以递归方式包含标头中的标头,因此会发生正确的事情-TStack会在QStack使用它之前声明。

  

解决此问题的另一种方法是像这样向前声明您的类型:

struct TStack;

class DLLDIR QStack {
public:
  TStack *Push(TStack *, int);
  // etc...

这样,编译器知道该类型应该存在,并且将推迟直到链接担心细节为止。请注意,这有一些警告。这是一个前向声明,不是定义。因此,如果您想访问任何TStack成员,则需要在作用域中具有完整的结构定义,即-头文件。必须先定义TStack,然后再进行my_t_stack->value之类的操作,否则编译器不会推迟直到链接确定::value是否为成员以及其类型为?

  • 顺便说一句,using namespace std;

不要那样做,这是个坏习惯,它会污染您的命名空间,并会导致编译时间缩短和编译器错误。相反,更喜欢在较窄的范围内引入符号。

答案 1 :(得分:0)

您是否已选中删除此项:

#include

 #include "stdafx.h"
    #include "QStack.h"
    #include 
    using namespace std;

答案 2 :(得分:0)

我注意到那里有几个错误。
这是代码的固定版本(至少可以编译:P)。
添加注释部分已修复。

QStack.h文件:

#pragma once


#ifdef QSTACK_EXPORTS
#define QSTACK_API __declspec(dllexport)
#else
#define QSTACK_API __declspec(dllimport)
#endif

// MOVED structures here. You might consider moving to another file and include them there as well.
struct Tstruct {
    int value;
    Tstruct * next;
};

struct TStack {
    int value;
    TStack *next;
};

class QStack // < - Removed "DLLDIR" as it was not compiling because of that   
{
public:
    TStack* Push(TStack *, int);
    void StackInit(TStack* *);
    int Pop(TStack* *);
    void queueInit(Tstruct * *, Tstruct * *);
    void enqueue(Tstruct * *, Tstruct * *, int);
    int Dequeue(Tstruct* *, Tstruct* *);
};

QStack.cpp文件:

#include "QStack.h"

// Added class name "QStack::" before function name to indicate that that's a member of the class 
void QStack::StackInit(TStack* *TOP) {
    *TOP = nullptr;
};

TStack* QStack::Push(TStack *a_top, int a_value) {
    TStack *l_hlp;
    l_hlp = new TStack;
    l_hlp->next = a_top;
    l_hlp->value = a_value;
    return l_hlp;
};

int QStack::Pop(TStack* *a_top) {
    TStack *l_hlp;
    int l_val;
    l_hlp = *a_top;     
    *a_top = l_hlp->next;
    l_val = l_hlp->value;
    delete l_hlp;           
    return l_val;
};

这是代码段,以防万一您需要: https://onlinegdb.com/r1zVLxMcE

答案 3 :(得分:0)

在QStack.cpp文件中

#include "stdafx.h"
#include "QStack.h"
#include <iostream>
using namespace std;
struct Tstruct {
    int value;
    Tstruct * next; 
};
struct TStack {
    int value;
    TStack *next;
};
void StackInit(TStack *TOP) {
    *TOP = NULL;
};
TStack* Push(TStack *a_top, int a_value) {
    TStack *l_hlp;
    l_hlp = new TStack;
    l_hlp->next = a_top;
    l_hlp->value = a_value;
    return l_hlp;
};
int Pop(TStack *a_top) {
    TStack *l_hlp;
    int l_val;
    l_hlp = *a_top;
    *a_top = l_hlp->next;
    l_val = l_hlp->value;
    delete l_hlp;
    return l_val;
};

在QStack.h中

// QStack.h - Contains declarations of some functions
#pragma once
#ifdef QSTACK_EXPORTS
#define QSTACK_API __declspec(dllexport)
#else
#define QSTACK_API __declspec(dllimport)
#endif
class DLLDIR QStack {
    public:
        TStack* Push(TStack *next, int value);
        void StackInit(TStack *TOP);
        int Pop(TStack *a_top);
        void queueInit(Tstruct *FRONT, Tstruct *REAR);
        void enqueue(Tstruct *FRONT, Tstruct *REAR, int value);
        int Dequeue(Tstruct *FRONT, Tstruct *REAR);
};

这可能有效。我发现的错误是:  -这种分配参数的语法是错误的void StackInit(TStack * *);。相反,您可以使用此语法void StackInit(TStack *TOP);对其进行分配,或者,如果您必须分配一个包含指向该指针的指针的参数,则应遵循此语法void StackInit(TStack **TOP);

  1. 是的,您可以在头文件中声明函数。
  2. 您也可以在头文件中或QStack.cpp文件中声明数据结构类型。
  3. 之后,您可以尝试构建QStack.cpp文件以获取DLL文件。
  

随时编辑以上代码。让我知道程序中是否有任何错误。