力为的技术博客

联系 聚合 管理
  154 Posts :: 1 Stories :: 561 Comments :: 0 Trackbacks

当把子类对象的指针赋值给父类时,不需要cast。shared_ptr也这样, 比如:

 

class A
{
public:
A();
virtual ~A();
}
;

class B: public A
{
public:
 B();
 
virtual ~B();
}
;

typedef shared_ptr
<A> APtr;
typdef shared_ptr
<B> BPtr;

BPtr pB(
new B());
APtr pA 
= pB;

这是期望的行为。继续:

class C
{
public:
  C();
  
~C();

  
const APtr& GetB() const return m_pB; }
private:
  BPtr m_pB;
}
;


问题出在哪里?

 

---------------------------------------------
m_pB转换为APtr类型时,产生临时对象。C::GetB()返回的是临时对象的引用。


一般情况下,没人会写这样的程序。返回临时对象的引用时候,编译器也会有warning。假如,忽略了warning,就有可能发生杯具。

posted on 2011-04-01 18:09 力为 阅读(2763) 评论(11)  编辑 收藏 引用 所属分类: 4. C++ FAQ

评论

# re: 失足于shared_ptr[未登录] 2011-04-01 21:32 vincent
加个const呢?  回复  更多评论
  

# re: 失足于shared_ptr 2011-04-01 21:38 空明流转
呃。难道你到现在都不晓得咩。。。  回复  更多评论
  

# re: 失足于shared_ptr[未登录] 2011-04-01 21:48 vincent
话说加个const,编译器会做处理吗?  回复  更多评论
  

# re: 失足于shared_ptr 2011-04-01 22:11 yiphon
为何会返回临时对象? 不是返回m_pB的引用吗?
  回复  更多评论
  

# re: 失足于shared_ptr 2011-04-02 09:53 溪流
返回的不是临时对象的引用。
之所以 warining,是因为 m_pB 会随着 C 对象的析构而消亡,此时,之前有这个返回的引用就成了孤魂野鬼了。m_pB 在类外的地位就是一个局部变量。  回复  更多评论
  

# re: 失足于shared_ptr[未登录] 2011-04-02 11:35 vincent
赞一个= =昨天没仔细看题意。。我又2了。。
返回了m_pB做类型转换的时候产生的临时变量的ref,就像ls所说,孤魂野鬼,这并不是调用者对这个函数的期望
  回复  更多评论
  

# re: 失足于shared_ptr 2011-04-02 11:42 空明流转
还好,这个一般也会获得返回值优化的。
一般牵涉到类型转换,返回的时候都要小心。  回复  更多评论
  

# re: 失足于shared_ptr 2011-04-02 14:21 力为
补上正确的写法:

class C
{
public:
C();
~C();

const BPtr& GetB() const { return m_pB; }
private:
BPtr m_pB;
};
  回复  更多评论
  

# re: 失足于shared_ptr 2011-04-10 00:03 flyinghearts
@力为
虽然 B与A存在继承关系,但BPtr与APtr可不存在这层关系,要返回APtr的引用,就必须要先创建一个APtr对像。

APtr pA = pB;
写成 APtr pA = static_pointer_cast<A>(pB);
比较好吧。
  回复  更多评论
  

# re: 失足于shared_ptr 2011-04-11 09:27 力为
@flyinghearts
我想shared_ptr隐式转换的行为在于与pure ptr保持一致。
所以尽管,BPtr与APtr不存在继承关系,仍然可以有APtr pA = pB;
上面的错误确实是由于隐式转换产生的临时对象引起的。即使成 APtr pA = static_pointer_cast<A>(pB); ,仍然有临时对象产生。  回复  更多评论
  

# re: 失足于shared_ptr 2011-04-13 23:22 flyinghearts
@力为

因为BPtr与APtr不存在继承关系,二者间的转换一定会产生临时对象。
写成 APtr pA = static_pointer_cast<A>(pB);
显示转换对象,是给自己提个醒,也方便以后维护代码。

  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理