C++ 常量引用包装器
我在马克·艾伦·韦斯的《数据结构》一书中看到了以下代码C++ 常量引用包装器,c++,pointers,constructor,constants,C++,Pointers,Constructor,Constants,我在马克·艾伦·韦斯的《数据结构》一书中看到了以下代码 template <class Object> class Cref { public: Cref ( ) : obj ( NULL ) { } explicit Cref( const Object & x ) : obj ( &x ) { const Object & get( ) const { if ( isNull( ) ) throw NullPointerException( ) ; e
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;
};
模板
类Cref
{
公众:
Cref():obj(NULL){}
显式Cref(常量对象和x):对象和x{
const对象&get()const
{
if(isNull())
抛出NullPointerException();
其他的
返回*obj;
}
bool isNull()常量
(返回obj==NULL;}
私人:
常量对象*obj;
};
因此,这里的要点是分配null/初始化常量引用。但我不确定我是否理解以下内容:
1.我们用另一个常量引用x初始化一个常量引用。但为什么它再次作为obj(&x)进行?常量对象中的&x与obj(&x)中的&x不同?我看到了这一点,但不太清楚为什么会这样。请解释。
2.get方法()-我们尝试返回此类的私有成员obj的常量引用。它已经是常量引用。为什么返回*obj而不仅仅是obj?
3.为什么使用显式关键字?如果发生隐式类型转换,会发生什么情况?有人能提供一个场景吗
谢谢1)obj(&x)
中的&x
用作操作员的地址
2) 不,它是指针。它的时间是Object*
,而不是Object&
3) 防止从可能具有自己的类型转换运算符的不兼容指针类型转换
C++提供了三种类型的null:
-过时;仅用于检查返回指针的C函数的返回值NULL
-已弃用;标准中将文本零定义为空指针0
-从C++11开始,这是测试null的首选方法。此外,nullptr
是类型安全的nullnullptr\t
obj
的类型为Object*
,但构造函数采用引用。因此,要获取指针,必须应用运算符的地址&
。成员是指针,因为它可以为NULL(在默认构造函数中设置),引用永远不能为NULL和有三种含义:
- 运算符的一元地址:取任何左值表达式的地址,给出指向该对象的指针
- 引用符号:在声明中,表示引用类型
- 二进制位AND运算符-此处不使用
因此,了解您是在看一个声明还是一个表达式是很重要的
explicit Cref( const Object & x )
这里,符号出现在函数参数的声明中,这意味着参数x
的类型是对对象的引用,该对象是常量
: obj ( &x ) {}
这里,运算符用于成员初始值设定项表达式。成员obj
初始化为指向x
的指针
2) 由于成员obj
实际上是一个指针,因此需要解引用运算符一元*
来获取引用
3) 一般来说,在任何(非复制)构造函数上使用显式是一个好主意,它可以只接受一个参数。不幸的是,这种语言并没有默认为显式的,当你想要的时候,它会让你使用某种“隐式”关键字。在这种情况下,如果构造函数是隐式的,那么可能会发生一件非常糟糕的事情:
Object create_obj();
void setup_ref(Cref& ref) {
ref = create_obj();
}
没有编译器错误或警告,但是setup\u ref
函数存储指向临时对象的指针,该指针在函数返回时无效 1)obj的类型不是引用,obj是指针,常量指针必须用地址初始化,因此必须应用运算符&的地址。
2) get()方法返回的引用不是对类成员obj的引用,而是对obj指向的对象的引用,因此必须使用*来遵从它。
3) 关键字explicit意味着我们拒绝隐式转换,也就是说,我们告诉编译器,不要使用此构造函数为我们进行隐式转换。
例如:
类别Cref A
对象B
A=B代码>
没有显式表达式也可以——因为我们需要右侧的Cref对象,编译器将使用构造函数Cref(constobject&B)自动生成Cref对象。但是如果添加显式,编译器将不会进行转换,将出现编译错误。感谢您的澄清!尤其是#2!:)关于#1,这意味着这是一个与声明有关的问题。因为我们只能声明一个const引用,比如const Object&x;当实际将其分配给指针时,ptr=&x不可避免地完成了。我的理由正确吗?@suprajayakumar:从逻辑的角度来看,引用基本上命名了一个对象。也就是说,在构造函数内部,传递给它的对象具有名称x
(并且是常量,因为它是常量引用)。因此,使用x
与使用该类型的变量完全相同。要获得指向变量的指针,可以使用运算符的加法,&
,因此对x
也可以这样做。引用也是使用符号&
定义的,这一事实在逻辑上与此无关。如果他们决定使用关键字ref
,情况也会一样。