是否可以在c ++中强制传递依赖对象的constness
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否可以在c ++中强制传递依赖对象的constness相关的知识,希望对你有一定的参考价值。
这是我想要阻止的:
class Dep; //for "dependency"
class C {
private:
const Dep& dep_; //or std::shared_ptr if I want to guarantee proper lifetime of dependency
public:
C(const Dep& dep) : dep_(dep){}
}
Dep d(Arg arg);
C obj(d); //obj can't change d
d.some_non_const_method(); //But it's creator can :(
我想得到的是,创建C
对象的唯一正确方法是这样的:
Dep d(Arg arg);
d.some_non_const_method();
const Dep d1(d); //or move constructor if appropriate
C obj(d1); //Object d1 must be const!
d1.some_non_const_method(); //compile error, so obj can be sure that the dependency he's got is really const.
有没有办法通过语法强制执行此操作?
附:依赖是为了共享,所以我不能在这里使用std::unique_ptr
。
我认为没有办法通过语法直接强制执行此操作。
问题是任何Dep&
都可以自由转换为const Dep&
。正如你正确地指出采取const Dep &d
并不意味着它是恒定的,而是承诺你的功能永远不会修改d
。
当其他答案巧妙地使用重载和删除方法来创建错误时,只要直接传递非const Dep,当从其他地方传递const Dep &
时,这些方法会失败。
// this could be arbitrarily complex and nested
std::unique_ptr<C> makeC(const Dep &d) {
return std::make_unique<C>(d);
}
void test() {
Dep nonConstDep;
auto pC = makeC(nonConstD); // conversion to const & is legal
nonConstDep.mutate(); // Nooo!
}
你需要的是一个不可变的dep类,它不允许变异和转换。
由于我不知道您是否可以更改Dep
类以及如何在程序的其他部分使用它,我建议使用此解决方案:
创建一个ImmutableDep
包装器,它有一个私人const Dep
。然后你可以限制你的类只采用ImmutableDep引用。
class ImmutableDep {
const Dep dep_;
public:
inline const Dep &get() const { return dep_; }
};
class C {
const Dep &dep_;
public:
// we know that an ImmutableDep's dep really is immutable
C(const ImmutableDep &dep) : dep_(dep.get()) {}
}
通过这种方式,您可以根据需要将const或非const引用传递给ImmutableDep
,始终保证私有包装的Dep
是不可变的。
如果你只需要在有限的“构造”阶段修改Dep
,我建议使用Builder pattern并在完成后创建一个不可变对象,也许将任何大的东西移动到不可变对象中。
如果我正确理解你的问题,你只想接受一个const
参数,并希望在传递非const
参数时出错。
最简单的方法应该是将非const
版本标记为delete
:
class C {
private:
const Dep& dep_;
public:
C(const Dep& dep) : dep_(dep){}
C(Dep &) = delete;
};
然后:
Dep d;
C obj(d); // Error, deleted function selected
const Dep d1(d);
C obj(d1); // ok
形式的东西
class C
{
C() = default;
friend class D;
};
class D
{
public:
C create_C() = delete;
C create_C() const {return C};
};
会做的。我已经建造了C
private
。 D
可以访问它,因为它是friend
的C
。 const
的非create_C
超载被删除。
以上是关于是否可以在c ++中强制传递依赖对象的constness的主要内容,如果未能解决你的问题,请参考以下文章