当您将ROOT对象作为参数传递给C++中的函数时,您可以访问该对象中的方法吗
Can you access methods from a ROOT object when you pass the object as an argument to a function in C++?
请原谅我的无知,但我是C++和ROOT的新手,我不知道自己到底做错了什么。
我想做的是编写一个函数,返回直方图中n个峰值的bin位置。以下是我的代码:
#include <iostream>
#include <algorithm>
#include <iterator>
#include "TROOT.h"
#include "TCanvas.h"
#include "TH1.h"
#include "TF1.h"
using namespace std;
int *peak_counter1d(TH1F *histogram,int peak_num,int threshold = 5,int display = 0){
if(display == 1){
TCanvas *look = new TCanvas("look","look",500,400);
histogram->Draw();
}
int total_bins = histogram->GetNBinsX();
double peak_bins[peak_num];
peak_bins[0] = histogram->GetMaximumBin();
int counter = 1;
int *check_array; // to put previously found peak bins
while(counter < peak_num){
double peak = threshold;
double peak_loc = -500;
check_array = new int[counter];
for(int i=0; i<counter; i++){
check_array[i] = peak_bins[i]; // fills the array with previously found peak bins
}
for(int i=0; i<total_bins; i++){
if(peak < histogram->GetBinContent(i)){
bool exists = find(begin(check_array),end(checkarray),i); // makes sure this is a peak we haven't already found
if(!exists){
peak = histogram->GetBinContent(i);
peak_loc = i;
}
}
}
peak_bins[counter] = peak_loc;
counter ++;
}
delete[] check_array;
return peak_bins;
}
void testing(){
gROOT->Reset();
TH1F *histo = new TH1F("histo","try",100,0,10);
TF1 *f1 = new TF1("f1","exp(-x/10)*sin(x)*sin(x)",0,10);
double val;
for(int i=0; i<100; i++){
val = f1->Eval(i/10.0);
//cout << i << "t" << i/100.0 << "t" << val << endl;
histo->SetBinContent(i,val);
}
int *peak_bins;
peak_bins = peak_counter1d(histo,3,5,1);
for(int i=0; i<3; i++){
cout << i << "t" << *(peak_bins+i) << endl;
}
}
当我在ROOT中执行此代码时,我得到以下内容:
root [] .x testing.cpp
Error: Can't call TH1F::GetNBinsX() in current scope testing.cpp:15:
Possible candidates are...
(in TH1F)
(in TH1)
*** Interpreter error recovered ***
我认为这是访问函数内部对象方法的问题,因为当我在testing((函数中调用histo->GetNBinsX((方法时,我不会遇到任何问题。但是我不知道。
谢谢你,如果我正在做其他灾难性的可怕的编码实践,请告诉我。
已经指出,不能返回局部变量的地址,当函数结束时,该地址将被销毁。
你的另一个问题是:
histo->GetNbinsX()
不起作用。我试着在主脚本和脚本的子例程中调用它:它非常适合我,使用当前的ROOT版本。在这个问题中,您拼错了GetNBinsX
(是的,这将与骆驼式策略更加一致(。可能
无论如何,我相信你会很高兴知道ROOT有一个非常智能的1D峰值搜索算法可以使用:寻找TSspectrum类。
您的代码存在各种问题。
最引人注目的是这个:
int *peak_counter1d(TH1F *histogram,int peak_num,int threshold = 5,int display = 0)
{
//...
double peak_bins[peak_num];
//...
return peak_bins;
}
您正在返回一个指向局部变量的指针。返回指向局部变量的指针是未定义的行为。
下一个问题是:
int *check_array; // to put previously found peak bins
while(counter < peak_num)
{
//...
check_array = new int[counter];
}
delete[] check_array;
您有潜在的内存泄漏,因为您正在循环而从未释放check_array
。另一个问题是,如果该循环从未执行,那么您正在对未初始化的变量调用delete []
。
下一个问题是:
int * peak_counter1d(...)
{
double peak_bins[peak_num];
//...
return peak_bins;
}
即使可以安全地返回指向局部变量的指针,函数也会返回int*,但返回的是double *
。
下一个问题是:
TCanvas *look = new TCanvas("look","look",500,400);
您正在分配look
,但从未解除分配,甚至从未使用过它
您也可以在main
:中执行相同的操作
TH1F *histo = new TH1F("histo","try",100,0,10);
TF1 *f1 = new TF1("f1","exp(-x/10)*sin(x)*sin(x)",0,10);
C++不是Java。您不必使用new
创建对象。
TH1F histo("histo","try",100,0,10);
TF1 f1("f1","exp(-x/10)*sin(x)*sin(x)",0,10);
除了最后一个问题外,如果您使用std::vector
而不使用new[]
来创建动态阵列,那么总体而言,这些问题都可以得到解决。
应用这些更改,代码应该看起来像这样(未编译(:
#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
#include "TROOT.h"
#include "TCanvas.h"
#include "TH1.h"
#include "TF1.h"
using namespace std;
vector<int> peak_counter1d(TH1F *histogram,int peak_num,int threshold = 5,int display = 0)
{
if(display == 1)
{
// TCanvas *look = new TCanvas("look","look",500,400);
histogram->Draw();
}
int total_bins = histogram->GetNBinsX();
vector<int> peak_bins(peak_num);
peak_bins[0] = histogram->GetMaximumBin();
int counter = 1;
vector<int> check_array; // to put previously found peak bins
while(counter < peak_num){
double peak = threshold;
double peak_loc = -500;
check_array.resize(counter);
for(int i=0; i<counter; i++){
check_array[i] = peak_bins[i]; // fills the array with previously found peak bins
}
for(int i=0; i<total_bins; i++){
if(peak < histogram->GetBinContent(i)){
bool exists = find(begin(check_array),end(checkarray),i); // makes sure this is a peak we haven't already found
if(!exists){
peak = histogram->GetBinContent(i);
peak_loc = i;
}
}
}
peak_bins[counter] = peak_loc;
counter ++;
}
return peak_bins;
}
void testing(){
gROOT->Reset();
TH1F histo("histo","try",100,0,10);
TF1 f1("f1","exp(-x/10)*sin(x)*sin(x)",0,10);
double val;
for(int i=0; i<100; i++){
val = f1.Eval(i/10.0);
//cout << i << "t" << i/100.0 << "t" << val << endl;
histo.SetBinContent(i,val);
}
vector<int> peak_bins = peak_counter1d(&histo,3,5,1);
for(int i=0; i<3; i++){
cout << i << "t" << peak_bins[i] << endl;
}
}
- 按基类对象访问派生类资源时出错
- 使用基类对象访问派生的仅类方法
- 从 const 对象访问非 const 方法
- 如何在C++中使用类对象访问指针数据成员
- 如何通过不同的指针使用类的对象访问结构?(链表)(C++)
- 使用二进制搜索树中的迭代器对象访问左侧节点
- 为什么引用类型在使用临时对象访问时是左值
- 从父对象 c++ 访问子方法
- 无法通过指针或对象 c++ 访问受保护的成员
- 为什么可以从类中的对象访问类的私有变量
- 对类似"struct {double, int}"对象使用reinterpret_cast进行对象访问
- 通过无符号 char 别名进行对象访问,加载和存储时会发生什么?
- 从对象访问结构枚举
- 如何全局创建对象并使用该对象访问全局范围内的公共成员函数
- 在C 中,可以从第三个共享对象访问其他两个不同共享对象
- 如何在C 中提供一个可呼叫的对象访问,例如lambda
- C 向量对象访问
- C++是否可以从同级第二个派生对象访问第一个派生对象的受保护基础数据成员?
- 如何从类内实例化的对象访问私有变量
- 多态性:通过类文本或对象访问静态成员