参考类成员的constness

时间:2011-06-20 21:30:31

标签: c++ const

我有几个类,其中一个类继续引用其他类的对象:

class Inner {};

class Outer {
    Inner & in;

public:
    Outer(Inner & in) : in(in) {}
};

如果我必须从const引用到Inner创建外部对象怎么办?我是否必须写出具体的课程,比如说OuterConst?

UPD :使用模板的任何简洁解决方案?为了避免在OuterConst类中重复代码。

UPD2 :当Inner没有const时,它应该是可修改的(因此我不能在当前的Outer实现中将const添加到Inner成员中。)

4 个答案:

答案 0 :(得分:6)

  

如果我必须从const引用到Inner创建外部对象怎么办?

嗯,你不能。这就是它。如果Outer只需要调用Inner的const成员函数,那么使它成为const引用 - 否则,你的类依赖于一个可变的Inner对象,你不应该从const引用创建一个外部对象。

答案 1 :(得分:3)

问题是Outer是否需要修改Innerin。如果是,则应将in保留为Inner &。在这种情况下,如果您有const Inner &,那么当然您无法将其传递给Outer,因为该引用不允许您修改引用的Inner,但是{{1确实需要修改Outer

如果Inner不需要修改Outer,那么您应该将Inner写为in,在这种情况下const Inner &可以初始化使用OuterInner &

你当然可以写:

const Inner &

然后初始化class Inner {}; template <class T> class Outer { T& in; public: Outer(T& in) : in(in) {} }; Outer<Inner>类型的对象。但Outer<const Inner>必须在这两种情况下做一些不同的事情,否则你只能Outer成为in。在这种情况下,你可能更好地编写单独的类,因此明确表示const Inner &做了不同的事情。

答案 2 :(得分:1)

这取决于。如果Outer的两个角色对于不同的constness都不同(一个必须编辑,另一个不能编辑),那么是。

但是如果两个角色相同(这意味着不会对const或非const引用进行任何更改),那么只需要将const Inner&作为参数。如果传递了非const参数,它将自动“提升”为const参数。

答案 3 :(得分:1)

您可以存储一个const引用,并在需要时使用const_cast来转换const。如果你添加一些运行时检查,它也是安全的。

class Inner { /* ... */ };

class Outer {
    Inner const & in;
    bool const inIsConst;

    Inner & inMutable()
    {
        if (inIsConst)
            throw std::logic_error("in is const.");
        else
            return const_cast<Inner &>(in);
    }

public:
    Outer(Inner const & in) : in(in), inIsConst(true) {}
    Outer(Inner & in) : in(in), inIsConst(false) {}

    // always safe
    void Foo() { std::cout << in.getFoo(); }

    // will throw if *this was constructed with a const Inner
    void Bar() { inMutable().setFoo(in.getFoo() + 1); }
};

当然,你总是可以把它分成两个类:一个不能改变in,另一个可以改变。{/ p>

要做到这一点,你可以派出一个可以改变in的类,而这个类不能。或者您可以从具有共同功能作为受保护成员的公共基类派生,并在派生类中使用using Base::Function公开适当的基类。