将构造函数标记为 __explicitly__ 需要对象类型
Posted
技术标签:
【中文标题】将构造函数标记为 __explicitly__ 需要对象类型【英文标题】:Mark constructor as __explicitly__ requiring an object type 【发布时间】:2011-12-09 02:55:43 【问题描述】:我有一个接受Material
类型对象的构造函数:
SomeClass::SomeClass( const Material& mat ) ;
但是,Material
允许通过 Vector
进行构造:
Material::Material( const Vector& v ) ;
因此,SomeClass
可以允许由Vector
构造:
SomeClass m( vec ) ; // valid, since vec is constructed to a Material first,
// then is passed to the SomeClass(Material) ctor
但是,在使用这种类型的 ctor(在同一个项目的不同类中!)不止一次“射自己的脚”之后,我想禁止构造SomeClass
直接由 Vector
对象组成,而不是始终需要传递 Material
。
有没有办法做到这一点?不知何故认为它与explicit
关键字有关。
【问题讨论】:
¤ 您可以将Material::Material
构造函数标记为explicit
。在 C++03 中,您还必须确保在 Vector
类中没有 operator Material
。但是,使用 C++11,您还可以将这样的转换运算符标记为 explicit
(最好是恕我直言,以避免转换运算符,而是通常通过命名函数提供转换)。干杯&hth.,
【参考方案1】:
您声明Material(const Vector &v)
为explicit
;这可以防止从一个到另一个的隐式转换。
这当然不是对SomeClass
的具体限制;这是对任何隐式转换实例的全球禁令。
【讨论】:
【参考方案2】:如果不影响从 Vector
透明构造 Material
的能力,您将无法做到这一点。
如果你让Material
的构造函数explicit
explicit Material( const Vector& v ) ;
那么你将总是必须写Material(v)
来构造一个实例。这将防止您意外地用 Vector
实例化 SomeClass
,但它也会破坏所有计算结果为 Vector
的表达式,其中应该是 Material
。
这是有道理的,因为通过不声明构造函数explicit
,您是在说“无论上下文如何,Vector
都与Material
一样好”。然后你不能后退半步说“哦,好吧,除非在构造 SomeClass
时”。
【讨论】:
是的!这是一个很棒的功能!【参考方案3】:制作Material
explicit
的构造函数:
explicit Material(const Vector& v) ...
或者,如果您不想这样做,作为一个 hack 并以const
-正确性作为牺牲,请从const Material& mat
中删除const
。您将无法将临时对象传递给 SomeClass
的构造函数(或 const
实例,这可能是一个太大的牺牲)。但是,这使您无法执行您可能想做的SomeClass(Material(v))
。所以只能接近自己想要的,但恐怕不是完全可以的。
【讨论】:
从构造函数参数中删除const
可以达到目的,但不可取。
@OliCharlesworth 是的,这就是为什么我说这有点像 hack。我只是想让他知道所有选项,也许他不知道临时变量只能作为 const
引用传递,而不仅仅是引用。以上是关于将构造函数标记为 __explicitly__ 需要对象类型的主要内容,如果未能解决你的问题,请参考以下文章