常量引用包装器
Constant Reference Wrapper
我在Mark Allen Weiss关于数据结构的书中遇到了以下一段代码。
template <class Object>
class Cref
{
public:
Cref ( ) : obj ( NULL ) { }
explicit Cref( const Object & x ) : obj ( &x ) {
const Object & get( ) const
{
if ( isNull( ) )
throw NullPointerException( ) ;
else
return *obj;
}
bool isNull( ) const
( return obj == NULL; }
private:
const Object *obj;
};
所以这里的重点是分配 null/初始化一个常量引用。但我不确定我是否理解以下内容:1. 我们用另一个常量引用 x 初始化一个常量引用。但是为什么它又作为 obj(&x( 完成?&in const Object & x 与 obj(&x( 中的 &x 不同?我看到了这一点,但不是很清楚为什么会这样。请解释一下。2. get 方法(( - 我们尝试返回此类的私有成员 obj 的 const 引用。它已经是一个常量引用。为什么返回 *obj 而不仅仅是 obj ?3. 为什么是显式关键字?如果发生隐式类型转换,会发生什么?有人可以为此提供场景吗?
谢谢
-
成员
obj
的类型为Object*
,但构造函数接受引用。因此,要获取指针,必须应用地址运算符&
。成员是一个指针,因为它可以是 NULL(在默认构造函数中设置(,而引用永远不能为 NULL。 -
私有成员不是常量引用,而是常量引用。取消引用它以获取引用。
-
在这种特定情况下,我也看不到潜在的隐式转换的任何负面影响。
1( obj(&x)
中的&x
用作地址运算符。
2(不,这是一个指针。它的时间是Object *
,而不是Object &
。
3( 防止从不兼容的指针类型进行转换,这些指针类型可能具有自己的类型转换运算符。
C++有三种可用的 null 版本:
-
NULL
- 过时;仅用于检查返回指针的 C 函数的返回值 -
0
- 已弃用;文本零在标准中定义为空指针 -
nullptr
- 从 C++11 开始,这是测试 null 的首选方法。此外,nullptr_t
是类型安全的 null。
1(令牌&
有三个含义:
- 一元地址运算符:获取任何左值表达式的地址,并提供指向该对象的指针。 引用
- 符号:在声明中,表示引用类型。
- 二进制按位 AND 运算符 - 此处不使用
因此,重要的是要知道您是在查看声明还是表达式。
explicit Cref( const Object & x )
在这里,符号出现在函数参数的声明中,这意味着参数的类型x
是对const
Object
的引用。
: obj ( &x ) {}
此处,运算符用于成员初始值设定项表达式。 成员obj
被初始化为指向x
的指针。
2( 由于成员 obj
实际上是一个指针,因此需要取消引用运算符一元*
来获取引用。
3(一般来说,在任何可以只接受一个参数的(非复制(构造函数上使用explicit
是个好主意。 不幸的是,该语言不会默认为显式,而是让您在有意使用时使用某种"隐式"关键字。 在这种情况下,如果构造函数是隐式的,可能会发生一件相当糟糕的事情:
Object create_obj();
void setup_ref(Cref& ref) {
ref = create_obj();
}
没有编译器错误或警告,但该setup_ref
函数存储指向临时对象的指针,该指针在函数返回时无效!
1(obj的类型不是引用,obj是指针,const指针必须使用地址初始化,因此必须应用address-of运算符&。2( get(( 方法返回的引用不是对类成员 obj 的引用,而是对 obj 指向的对象的引用,因此您必须使用 * 来尊重它。3(关键字显式表示我们拒绝隐式转换,也就是说,我们告诉编译器,不要为我们使用此构造函数进行隐式转换。
例:
class Cref<Object> A;
Object B;
A=B;
没有显式也没关系 - 由于我们需要右侧的 Cref 对象,编译器将使用构造函数 Cref( const Object & B( 自动制作 Cref 对象。但是,如果添加显式,编译器将不会进行转换,并且会出现编译错误。
- 考虑引用和常量的可变参数函数包装器
- 将对象传递给函数而不将其包装到 std::ref 中,而参数被指定为 const 引用
- 自定义引用包装器的常量正确性
- libfreenect c++包装中未定义的引用
- 对类型的非常量左值引用 - 使用类类型的参数时,目标C++包装器中的错误
- 引用包装器的向量,push_back失败?
- 返回对 std::函数包装的 lambda 中静态变量的引用会导致段错误
- 非默认可构造和 std::引用包装器替代项的序列化
- 如何在 C++14 中编写用于调用 Fortran 函数的通用包装器(按引用调用 --按值调用>)
- 如何在 Cython 中包装引用的 c++ 类
- 将一包转发引用包装成元组
- 向量迭代器对于包装器类不可取消引用(没有超出 end() 取消引用)
- 如何将数据传递到引用包装器
- 如何在php中调用swig包装的C方法中的引用
- C++存储任意引用的包装类,但本身不是类模板
- 访问向量 c++11 中的引用包装元素
- OpenCL 1.1 使用C++包装器的未定义引用
- 在包装的临时文件中返回对象引用
- C++Opencl包装引用计数
- 当使用DllImport时,在c#中包装c++引用参数