【问题标题】:C++ Method declaration using another class使用另一个类的 C++ 方法声明
【发布时间】:2013-01-12 08:30:30
【问题描述】:

我开始学习 C++(来自 Java),所以请耐心等待。

我似乎无法让我的方法声明接受我创建的类。

“上下文”尚未声明

我认为我没有理解一个基本概念,但我不知道是什么。

表达式.h

#include "Context.h"  
class Expression {  
public:  
    void interpret(Context *);  // This line has the error
    Expression();  
    virtual ~Expression();  
};  

上下文.h

#include <stack>  
#include <vector>  
#include "Expression.h"  

class Context {  
private:  
    std::stack<Expression*,std::vector<Expression*> > theStack;  
public:  
    Context();  
    virtual ~Context();  
};

【问题讨论】:

标签: c++ class header


【解决方案1】:

您必须在Context 中转发声明Expression,反之亦然(或两者兼而有之),否则您有循环依赖。例如,

表达式.h:

class Context; // no include, we only have Context*.

class Expression {  
public:  
    void interpret(Context *);  // This line has the error
    Expression();  
    virtual ~Expression();  
};

上下文.h:

#include <stack>  
#include <vector>  

class Expression; // No include, we only have Expression*

class Context {  
private:  
    std::stack<Expression*,std::vector<Expression*> > theStack;  
public:  
    Context();  
    virtual ~Context();  
};

您可以执行前向声明,因为不需要类的完整定义,因为在每种情况下您只引用指向另一个类的指针。您可能需要在实现文件中包含这些内容(即,Expression.cpp 中的 #include "Context.h"Context.cpp 中的 #include Expression.h)。

最后,记得把include guards放在你的头文件中。

【讨论】:

  • 我的错,我只是忘了添加它们。它们实际上在我的代码中。
  • @spudfkc 好的,重点是循环包含依赖项,请参阅我的编辑。
【解决方案2】:

在 C++ 中,类定义总是必须以分号结尾 ; 例如:

class foo {};

Java 和 C# 不需要,所以我可以看出你的困惑。

而且看起来你的两个头文件都包含彼此。因此,它有点像一条蛇在吃它的尾巴:它从哪里开始?因此,在您的 Expression.h 中,您可以将“包含”替换为前向声明:

class Context;
class Expression {  
public:  
    void interpret(Context *);  // This line has the error
    Expression();  
    virtual ~Expression();  
}

最后但并非最不重要的一点是,您应该设置编译器保护以防止标头多次包含在 .cpp 文件中。您可以将#pragma once 放在头文件的顶部。如果您使用的是 Visual Studio 和 microsoft 编译器,这将非常有用。我不知道 GCC 是否支持它。或者你可以像这样包装你的头文件:

#ifndef EXPRESSION_H_
#define EXPRESSION_H_
    class Context;
    class Expression {  
    public:  
        void interpret(Context *);  // This line has the error
        Expression();  
        virtual ~Expression();  
    }
#endif

【讨论】:

  • 请勿使用以下划线后跟大写字母 (_EXPRESSION_H) 或包含两个连续下划线的名称。它们保留给实现。
  • 谢谢皮特。会修改的。
【解决方案3】:

您可能需要在 #include 之前的头文件中转发声明 Context 和 Expression 类

例如

    #include <stack>  
    #include <vector>  

// forward declaration   
class Context;
    class Expression;

    #include "Expression.h"  

    class Context {  
    private:  
        std::stack<Expression*,std::vector<Expression*> > theStack;  
    public:  
        Context();  
        virtual ~Context();  
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-08
    • 1970-01-01
    • 1970-01-01
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多