0

我正在编写一个函数来将某个特定类(二维直方图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 指针。在后一种情况下,会发生一些奇怪的事情:如果我调用 SafeCopy 并传递一个 NULL h_out 我会得到以下输出:

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 );
4

3 回答 3

0

您没有显示调用代码,但听起来问题来自类似SafeCopy(something, NULL). 是的,行不通。传入指针并返回结果:

TH2F *SafeCopy(constTH2F *in, TH2F *out) {
    if (!out)
        out = whatever;
    *out = *in; // or whatever...
    return out;
}
于 2013-03-27T18:26:33.260 回答
0

如果我调用 SafeCopy 传递一个 NULL h_out 我得到这个输出:
...
* 编辑 这是调用代码:
TH2F * h_smearedMigration;
...
SmartCopy( h_migration, h_smearedMigration );

那不是空指针,那是未初始化的指针。它包含随机垃圾,不太可能是 0x0。

于 2013-03-27T18:37:44.777 回答
0

首先,不清楚为什么要使用指针。理想情况下,您只想直接持有对象。那么您不需要特殊的复制约定:

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复制起来很昂贵,那么您可以通过 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);
于 2013-03-27T19:24:39.537 回答