"使用"类中的指令

时间:2016-02-10 03:23:10

标签: c++ namespaces

关注我之前的question。我已经决定使用using指令来替换类中的类别,以避免导入其他内容并污染使用这些违规标头的其他标头。

namespace MyLibrary {
    namespace MyModule1 {
        class MyClass1 {
        public:
            float X;
            float Y;

            MyClass1(float x, float y): X(x), Y(y) {}
        };
    } // namespace MyModule1

    namespace MyModule2 {
        class MyClass2 {
        private:
            // as suggested in linked question
            using MyCustomType1 = MyLibrary::MyModule1::MyClass1;

        public:
            void DoSomething(MyCustomType1 parameter) {
                std::cout << parameter.X << std::endl;
                std::cout << parameter.Y << std::endl;
            }
        };
    } // namespace MyModule2
} // namespace MyLibrary

int main(int argc, char* argv[])
{
    MyLibrary::MyModule1::MyClass1 some_parameter(1.0f, 2.0f);
    MyLibrary::MyModule2::MyClass2 some_var;

    // Can't do this
    // MyLibrary::MyModule2::MyClass2::MyCustomType1 some_other_var;

    // But I can do this
    some_var.DoSomething(some_parameter);
    return 0;
}

如果MyLibrary命名空间中的用户在某个类(私有)中存在别名,那么它们将如何知道MyCustomType1是什么?

我在using的使用是否合法,或者这是一个我不小心做的肮脏黑客?

1 个答案:

答案 0 :(得分:1)

他们会知道你必须#include这两个类的声明的简单原因。

阅读完这篇文章以及之前的问题,我认为这里缺少的概念是前向声明的概念。

考虑以下头文件,我们将此文件称为mymodule1_fwd.H

namespace MyLibrary {
    namespace MyModule1 {
        class MyClass1;
    } // namespace MyModule1
}

那就是它。这足以让您声明MyClass2

#include "mymodule1_fwd.H"

namespace MyModule2 {
    class MyClass2 {
    private:
        // as suggested in linked question
        using MyCustomType1 = MyLibrary::MyModule1::MyClass1;

    public:
        void DoSomething(MyCustomType1 parameter);
    };
} // namespace MyModule2

请注意,仅包含此头文件不会真正自动获取整个MyModule类声明。另请注意以下事项:

您无法定义内联DoSomething()类方法的内容,因为它实际上使用了别名类型。这会产生以下后果:

  • 您必须在某处(可能在DoSomething实施翻译模块中)定义.C()方法。

  • 同样,您必须从MyClass1头文件声明实际的mymodule1_fwd.H类。我在这里使用我自己的个人命名约定,&#34; filename_fwd.H&#34;对于前向声明,前向声明头文件;和&#34; filename.H&#34;对于实际的类实现,实现头文件。

  • DoSomething()方法的调用者必须显式#include MyClass的实际类声明头文件,因为他们必须将其作为参数传递。< / p>

您无法真正避免调用者必须知道他们实际用于传递参数的类。但只有DoSomething()方法的调用者才需要它。使用MyClass2的其他部分并且不调用DoSomething()的内容,不需要了解MyClass1的任何内容,并且实际的类声明赢得了&{除非他们明确#include类实现头文件,否则对他们可见。

现在,如果您仍然需要内联DoSomething(),出于性能原因,可以使用一些技巧,使用预处理程序指令,如果某人#include全部是必要的头文件,他们将获得DoSomething()方法的内联声明。

但那必须是另一个问题。