我有几个类,其中一个类继续引用其他类的对象:
class Inner {};
class Outer {
Inner & in;
public:
Outer(Inner & in) : in(in) {}
};
如果我必须从const引用到Inner创建外部对象怎么办?我是否必须写出具体的课程,比如说OuterConst?
UPD :使用模板的任何简洁解决方案?为了避免在OuterConst类中重复代码。
UPD2 :当Inner没有const时,它应该是可修改的(因此我不能在当前的Outer实现中将const添加到Inner成员中。)
答案 0 :(得分:6)
嗯,你不能。这就是它。如果Outer只需要调用Inner的const成员函数,那么使它成为const引用 - 否则,你的类依赖于一个可变的Inner对象,你不应该从const引用创建一个外部对象。如果我必须从const引用到Inner创建外部对象怎么办?
答案 1 :(得分:3)
问题是Outer
是否需要修改Inner
到in
。如果是,则应将in
保留为Inner &
。在这种情况下,如果您有const Inner &
,那么当然您无法将其传递给Outer
,因为该引用不允许您修改引用的Inner
,但是{{1确实需要修改Outer
。
如果Inner
不需要修改Outer
,那么您应该将Inner
写为in
,在这种情况下const Inner &
可以初始化使用Outer
或Inner &
。
你当然可以写:
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
公开适当的基类。