![](/img/trans.png)
[英]Dereferencing a pointer while passing to a reference expecting function creates a copy, why?
[英]Passing pointer by copy or by reference
我正在编写一个函数,将某个特定类的内容(二维直方图TH2F*
) TH2F*
到另一个TH2F*
。 说实话,我希望能够
SafeCopy( in, out )
其中, in
我输入TH2F*
和out
是我的目的地TH2F*
。 特别是,我想以这样一种方式实施SafeCopy
,以便在事先未分配out
时也能正常工作。 首先,我以这种(错误的)方式实现了该功能
void SafeCopy( const TH2F * h_in, TH2F *h_out )
{
cout << "SafeCopy2d: output histogram address is " << h_out << endl;
if( h_out != NULL )
{
cout << "SafeCopy2d: h_out has been identified as non-zero pointer\n";
(*h_out) = *h_in; // I'm making use of the copy-constructor
// it wouldn't work if h_out == NULL
}
else
{
cout << "SafeCopy2d: h_out has been identified as null pointer\n";
h_out = new TH2F( *h_in );
cout << "SafeCopy2d: h_out address is now " << h_out << endl;
}
}
输出是
SafeCopy2d: output histogram address is 0x0
SafeCopy2d: h_out has been identified as null pointer
SafeCopy2d: h_out address is now 0xblahblah
但是,这当然是行不通的,因为退出函数时,“真实”指针h_out仍为0,因为我是通过复制而不是通过引用传递的。 我将函数的原型(不更改其实现)更改为
void SafeCopy( const TH2F * h_in, TH2F *&h_out )
为了通过引用传递h_out指针。 在后一种情况下,会发生一些奇怪的事情:如果我通过一个NULL h_out调用SafeCopy,则会得到以下输出:
SafeCopy2d: output histogram address is 0x*a non-zero value*
SafeCopy2d: h_out has been identified as non-zero pointer
我的问题是:为什么如果我通过拷贝传递h_out,则它被正确识别为NULL指针,而当我通过引用传递它时,它显示为非零?
编辑这是调用代码:
//TH2F * h_migration is created and filled previously in the program
TH2F * h_smearedMigration;//
for (int ntoy=0; ntoy < NTOY; ntoy++ ) {
//matrix smearing
SmartCopy( h_migration, h_smearedMigration ); //copy the original matrix to a temporary one
RunToy( h_smearedMigration ); //smear the matrix
...
我想避免类似
h_smearedMigration = SmartCopy( h_migration, h_smearedMigration );
您尚未显示调用代码,但听起来问题出在诸如SafeCopy(something, NULL)
类的问题上。 是的,行不通。 传递指针并返回结果:
TH2F *SafeCopy(constTH2F *in, TH2F *out) {
if (!out)
out = whatever;
*out = *in; // or whatever...
return out;
}
如果我调用传递了NULL h_out的SafeCopy,则会得到以下输出:
...
*编辑这是调用代码:
TH2F * h_smearedMigration;
...
SmartCopy(h_migration,h_smearedMigration);
这不是NULL指针,而是未初始化的指针。 它包含随机垃圾,不太可能为0x0。
首先,不清楚为什么要使用指针。 理想情况下,您只想直接固定对象。 然后,您不需要特殊的复制约定:
TH2F RunToy(TH2F const &in);
//TH2F h_migration is created and filled previously in the program
for (int ntoy=0; ntoy < NTOY; ntoy++ ) {
TH2F h_smearedMigration = RunToy(h_migration);
如果TH2F
复制TH2F
很昂贵,那么您可以通过pImple之类的方式实现它,这样它可以便宜地移动,但仍然像值类型一样工作。
如果确实需要指针,则应该使用智能指针,并且永远不要拥有原始指针(例如,可以肯定拥有原始指针会使您的代码异常不安全)。
void RunToy(std::unique_ptr<TH2F> in_out);
void SafeCopy(TH2F const &in, std::unique_ptr<TH2F> &out)
{
if(h_out) {
*out = in; // copy assignment
} else {
out = make_unique<TH2F>(h_in); // copy construction
}
}
for (int ntoy=0; ntoy < NTOY; ntoy++ ) {
std::unique_ptr<TH2F> h_smearedMigration;
SmartCopy(h_migration, h_smearedMigration);
RunToy(h_smearedMigration );
当然,您通常不需要SmartCopy
函数来动态确定是使用副本分配还是使用副本构造。 根据是否已经分配了对象,您应该知道需要什么。
// std::unique_ptr<TH2F> h_migration is created and filled previously in the program
for (int ntoy=0; ntoy < NTOY; ntoy++ ) {
auto h_smearedMigration = make_unique<TH2F>(*h_migration);
RunToy(h_smearedMigration);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.