除了指针之外,C++还提供了行为类似的引用。除了这些内置类型之外,它还提供了构造模仿这种行为的自定义类型的选项。
以这两种自定义类型为例:
第一个
这两种类型的使用方式不同:
void f(const int& x);
auto r = Ref{};
auto p = Ptr{};
f(r);
f(*p);
这两种类型并不等同,但用途大致相同。在C++标准库中,示例类型有:
- 指针行为:
std::optional
、std::unique_ptr
- 参考行为:
std::reference_wrapper
、std::atomic
如果我们设计的自定义数据类型的指针行为和引用行为都是合理的,那么应该选择哪一种?
2条答案
按热度按时间ax6ht2ek1#
C++不允许重载
operator.
。因此,无论你做什么,都不可能以通用的方式实现ref.foo()
语法。例如,std::reference_wrapper
使用ref.get().foo()
语法,这是相当复杂的。除此之外,示例中的隐式转换很容易出错,通常不可取。
考虑到这些,我会将我的自定义类设计成类似指针的行为,因为这完全可以用当前的语言规则实现。
5lhxktic2#
这两种模型之间的一个区别是操作符的行为方式。
您可以让
Ptr{} + Ptr{}
的行为与*Ptr{} + *Ptr{}
不同。这对于
Ref{} + Ref{}
是不正确的,因为这里发生了隐式转换,并且因此如果Ref
上的operator+
的行为与其元素类型上的不同,则将非常容易出错。一般而言,对于
Ptr{}
,建模的是一种具有关系的关系:内部值独立于 Package 器。相反,Ref{}
模拟IS-A关系: Package 意味着固有地以与内部值相同的方式表现。