3 回答

TA贡献1846条经验 获得超7个赞
C++里引用其实只是受限的指针,只是在语义上限制不能对引用这一受限的指针做一些指针能做的操作:重新赋值,拷贝,++,--(暂时还没有想到其他的),并限制不允许为空,以提高安全性,可以理解为是编译器对指针的一种保护模式。
那么,考虑什么时候应该使用引用,又什么时候应该使用指针呢?我认为有几点:
引用优先
凡是能用引用代替指针的都用引用。
指针是允许为空的,而引用不允许。
const stock* top(...)
{
return NULL;
}
当然,这种情况下你还是可以坚持使用引用,然后空对象的情况下可以通过throw exception的方式来表达:
const stock& top(...)
{
throw null_top_stock_exception();
}
合理使用语义暗示,指针暗示拥有(has),引用暗示关联(use):
car has a wheel
class wheel {};
class car
{
wheel* _wheel;
public:
car() : _wheel(NULL) {};
void set_wheel(wheel* wheel) { _wheel = wheel; };
};
trip use a car:
class trip
{
const car& _car
public:
trip(const car& car) : _car(car) {};
};
当然,也是有例外,如果在trip的生存周期里,关联的_car是要求可变的,那就只能使用指针了(因为引用不可以重新赋值):
class trip
{
const car* _car
public:
trip(const car* car) : _car(car) {};
void set_car(const car* car) : _car(car) { _car = car; };
};
否则,坚持使用引用的话,想更改_car的指向,就只能重新构造一个新的trip了。
容器中不可保存引用,只能用指针(我猜主要是因为引用被限制了重新赋值及拷贝操作):
std::vector<car> cars; // OK
std::vector<car*> cars; // OK
std::vector<car&> cars; // ERROR
最后,随时可以把引用转化为指针:
class maintainer
{
public:
void maintain(car& car)
{
car* p = &car;
// play with pointer 'p'
}
};
但是一定要注意情景,这里car只是传进来供maintain方法使用(引用暗示use关系),取指针操作虽然不优雅,尚可以接受,但千万要注意把指针保存下来使用的情况:
class maintainer
{
car* _last_car;
public:
void maintain(car& car)
{
car* _last_car = &car;
// ...
}
void review_last_maintain()
{
// play with "_last_car"
}
};
在退出maintain方法后,_last_car指向的对象是很有可能会被释放的哦。
添加回答
举报