【问题标题】:Use private nested class in a public interface of an enclosing class [duplicate]在封闭类的公共接口中使用私有嵌套类[重复]
【发布时间】:2013-09-16 20:33:20
【问题描述】:

在实现自定义数据结构的过程中,我遇到了一个有趣的困境。不幸的是,我在 C++11 标准中找不到任何答案,所以我希望有人能给我解释一下。

有一个类有一个私有嵌套类。它还使用这个私有子类作为公共函数中的返回值。像这样:

class Enclosing {
private:
    // Private nested class
    struct Nested {
        Nested(int x) : _x(x) {}
        int _x;
    };

    Nested _nested;

public:
    Enclosing():_nested(42) {}

    // Use private nested class in public interface
    const Nested& get_nested() {
        return _nested;
    }
};

如果我尝试使用 call get_nested 它会编译,尽管我无法创建 Enclosing::Nested 类型的局部变量来存储结果。但这就是 auto 来救援的地方:

int main() {
    Enclosing e;
    //Enclosing::Nested n = e.get_ref( ); //Error! Enclosing::Nested is private
    auto n = e.get_nested( );             //Ok, unless we name a type
    cout << n._x << endl;
}

更重要的是,借助一些可变参数模板,我什至可以调用嵌套类的构造函数并为其创建一个新示例:

template<class T, typename... Args>
T* create(const T& t, Args... args) {
    return new T(args...);
}

int main() {
    Enclosing e;
    // We can even create a new instance of the private nested class
    auto np = create(e.get_nested( ), 68); 
    //Enclosing::Nested* np = create(e.get_nested( ), 68); // But don't name a type
    cout << np->_x << endl;
}

有人可以向我解释这种行为吗?为什么auto 允许我们访问其他私有数据类型?一定有一些明显的原因,到目前为止我还看不到。非常欢迎参考标准中的段落。

非常感谢!

(在 gcc 4.7.3 和 clang 3.2 中检查)

【问题讨论】:

  • 那就不要设为私有!

标签: c++ c++11


【解决方案1】:

除了解释它的副本之外,您实际上可以改进私有类作者的意图,方法是使内部类的成员私有并将外部类声明为friend .这样您的第二个示例 (create) 将不再编译(在实践中,添加一个显式且因此是私有的 copy-ctor):

class Nested {
    Nested(int x) : _x(x) {}
    int _x;
    friend class Enclosing;
};

这确保Nested 的所有实例都是从Enclosing 创建的。

【讨论】:

    猜你喜欢
    • 2016-04-30
    • 2015-07-21
    • 2014-09-21
    • 2018-08-13
    • 1970-01-01
    • 2014-06-18
    • 1970-01-01
    • 1970-01-01
    • 2014-02-01
    相关资源
    最近更新 更多