【问题标题】:Forward "Pre-declaring" a Class in C++在 C++ 中转发“预先声明”一个类
【发布时间】:2009-07-08 15:18:13
【问题描述】:

我有一种情况,我想声明一个类成员函数,它返回一个依赖于类本身的类型。举个例子吧:

class Substring {
    private:
        string the_substring_;
    public:
        // (...)
        static SubstringTree getAllSubstring(string main_string, int min_size);
};

而SubstringTree定义如下:

typedef set<Substring, Substring::Comparator> SubstringTree;

我的问题是,如果我将 SubstringTree 定义放在 Substring 定义之后,静态方法会说它不知道 SubstringTree。如果我反转声明,那么 typedef 会说它不知道 Substring。

我该怎么做?提前致谢。

【问题讨论】:

  • “预先声明”实际上称为“前向声明”,使用正确的术语会更幸运并获得更好的结果。
  • 对不起,我实际上忘记了这个词是什么。想想看,如果我知道这个词是什么,我很可能会知道如何去做我所要求的。 =)
  • 这就是为什么我们应该在答案或 cmets 中包含“前向声明”,这样您就会知道,并且任何其他遇到此问题的 C++ 新手都应该知道。

标签: c++ class substring


【解决方案1】:

正如你所写,简短的回答是你不能。

您确实有几个相近的选择:

1) 在子字符串中声明子字符串树

class Substring {
public:
    class Comparator;
    typedef set< Substring, Comparator> Tree;

private:
    string the_substring_;
public:
    // (...)
    static Tree getAllSubstring(string main_string, int min_size);
};

typedef Substring::Tree SubstringTree;

2) 在 Substring 之外定义 Comparator:

class Substring;
class SubstringComparator;
typedef set< Substring, SubstringComparator> SubstringTree;

class Substring {
public:

private:
    string the_substring_;
public:
    // (...)
    static SubstringTree getAllSubstring(string main_string, int min_size);
};

3) 您可以使用模板来延迟查找,直到您有更多声明:

template <typename String>
struct TreeHelper
{
  typedef set< String, typename String::Comparator> Tree;
};

class Substring {
public:
  class Comparator;

private:
  string the_substring_;
public:
  // (...)
  static TreeHelper<Substring>::Tree getAllSubstring(string main_string
                                             , int min_size);
};

typedef TreeHelper<Substring>::Tree SubstringTree;

【讨论】:

    【解决方案2】:

    你可以在类中定义它:

    class Substring {
        private:
            string the_substring_;
        public:
            // (...)
            typedef set<Substring, Substring::Comparator> SubstringTree;
            static SubstringTree getAllSubstring(string main_string, int min_size);
    };
    

    【讨论】:

    • 但是你必须用Substring::SubstringTree引用它
    • ... 这可能不是一个坏主意。这将有助于整理全局命名空间。我什至会选择 Substring::Tree。
    • 但是你可以在类之外添加另一个 typedef,在全局范围内重新定义它
    • @Ates Goral:是的,我认为Substring::Tree 实际上是最好的解决方案,但Substring::SubstringTree 有点多余。
    • 我将使用 Substring::Tree。谢谢!
    【解决方案3】:

    你可以用这个预先声明一个类:

    class Foo;
    

    请记住,在实际定义类之前,您只能声明指向它的指针,而不能声明实例。

    【讨论】:

      【解决方案4】:

      前向声明

      class Substring;
      

      我不知道这是否适用于 Substring 的非指针使用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-21
        • 2020-02-15
        • 1970-01-01
        相关资源
        最近更新 更多