【问题标题】:Access Object attributes in C++ [closed]在 C++ 中访问对象属性 [关闭]
【发布时间】:2014-10-30 02:42:23
【问题描述】:

我对 C++ 编程比较陌生,我编写的代码没有按预期执行。

代码有点长[粘贴在最后以供参考],但我将在代码中指出我的担忧:

我在一个while循环中定义了一个类的对象:

...

objVec[obj_i] = new ChipSeqRegion(refID, strand, midPoint, start, end, posArray, frac_posArray, negArray, frac_negArray);

        //testing
        cout<<"printing object number: "<<obj_i<<endl;
        objVec[obj_i]->PrintID();
        cout<<"printing frac pos array: "<<endl;
        objVec[obj_i]->PrintFracPosArray();
        obj_i++;
    }
    objVec[0]->PrintID();
        cout<<endl;
        objVec[0]->PrintFracPosArray();
        cout<<endl;
        objVec[1]->PrintID();
        objVec[1]->PrintFracPosArray();
        cout<<endl;
        objVec[2]->PrintID();
        objVec[2]->PrintFracPosArray();
} 

在上面的代码片段中,PrintID 和 PrintFracPosArray 只是用于打印变量/数组内容的过程[同一类的成员]。

现在,如果我尝试在循环内打印对象属性 refID 和 posArray,那么所有打印的值都会不同,并且符合分配和预期。

但在循环之外,printID 属性唯一地打印值 [如预期的那样],但 posArray 属性只是重复循环中最后分配的值。 我想在我关心的循环之外唯一地访问所有值。

我确信这可能来自范围冲突或变量传递的方式。

任何帮助都会很棒!!!

提前致谢。 快速查看下面的详细代码可以澄清任何问题:

详细代码:[对不好的介绍表示歉意]


#include <iostream>
#include <string>
#include <fstream>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <vector>
#include <iomanip>
#include <cmath>
#include "api/BamReader.h"
#include "api/BamWriter.h"
#include "api/BamAlignment.h"
#include "api/BamAux.h"

using namespace std;
using namespace BamTools;

BamReader reader;
BamAlignment al;

int const windowSize = 10;
int halfWindowSize = windowSize/2;
int const N = windowSize + 1;
//determine the gap score
float gap = -2;
//default value for matrix F
double negNum = -100000;


float F[N][N];
int xTraceBack[N][N];
int yTraceBack[N][N];

float maxScore;
int x_coord = 0;
int y_coord = 0;

//collections of arrays from chipSeq data after loading data
class ChipSeqRegion{
private:
    int ref_id, mid_p, start_p, end_p;
    char genomeStrand;
    float* pos_array;
    float* frac_positiveArray;
    float* neg_array;
    float* frac_negativeArray;
    float* gap;

public:

    ChipSeqRegion (int refID, char strand, int midPoint, int start, int end, float* posArray, float* frac_posArray, float* negArray, float* frac_negArray);


    //accessors
    int GetRefID(){return ref_id;}
    int GetMidPoint(){return mid_p;}

    void PrintID();
    void PrintFracPosArray();

    //destructor
    ~ChipSeqRegion(){
        delete [] pos_array;
        delete [] frac_positiveArray;
        delete [] neg_array;
        delete [] frac_negativeArray;
    }
};

ChipSeqRegion::ChipSeqRegion(int refID, char strand, int midPoint, int start, int end, float* posArray, float* frac_posArray, float* negArray, float* frac_negArray){

    ref_id = refID;
    genomeStrand = strand;
    mid_p = midPoint;
    start_p = start;
    end_p = end;
    pos_array = posArray;
    frac_positiveArray = frac_posArray;
    neg_array = negArray;
    frac_negativeArray = frac_negArray;
}


void ChipSeqRegion::PrintID(){
    cout<<"ref id is: "<<ref_id<<endl;
}

void ChipSeqRegion::PrintFracPosArray(){
    cout<<"this is raw pos data"<<endl;
    for (int i = 0; i<windowSize; i++){
        cout<<pos_array[i]<<'\t';
    }
    cout<<"this is frac data"<<endl;
    for (int i = 0; i<windowSize; i++){
        cout<<frac_positiveArray[i]<<'\t';
    }
    cout<<endl;
}


class ChipSeqLoader{
public:
    void LoadData (string bamFileName, string coordFileName);
    void GetRegions();
private:
    string nameOfBamFile;
    string nameOfCoordFile;
};

void ChipSeqLoader::LoadData(string bamFileName, string coordFileName){

    nameOfBamFile = bamFileName;
    nameOfCoordFile = coordFileName;

    int obj_i = 0;
    int objSize = 6;
    ChipSeqRegion **objVec = new ChipSeqRegion* [objSize];

    //reading coordinates
    ifstream CoordFile;
    char chrom[5], strand;
    string sChr1, sChr2, withmotif, dot;
    int start, end, midPoint;
    float tag;

    CoordFile.open(coordFileName.c_str());

    if (CoordFile.is_open()){
        while (!CoordFile.eof()){
            CoordFile>>chrom;
            CoordFile>>withmotif;
            CoordFile>>dot;
            CoordFile>>start;
            CoordFile>>end;
            CoordFile>>tag;
            CoordFile>>strand;
            CoordFile.ignore(200,'\n');

            midPoint = (start+end)/2;

            ostringstream convert1;
            ostringstream convert2;
            convert1<<chrom[3];
            convert2<<chrom[4];
            sChr1 = convert1.str();
            sChr2 = convert2.str();
            string sChrom;
            sChrom = sChr1+sChr2;
            int refID;
            if (sChr1 =="X\0"){
                refID = 19;
            }else if (sChr1 == "Y\0"){
                refID = 20;
            }else{
                refID = atoi(sChrom.c_str())-1;
            }

            int intStrand;
            if (strand == '+'){
                intStrand = 0;
            }else if (strand == '-'){
                intStrand = 1;
            }

            cout<<endl;
            cout<<sChrom<<'\t'<<refID<<'\t'<<start<<'\t'<<end<<'\t'<<midPoint<<'\t'
                    <<strand<<'\t'<<intStrand<<endl;

            //get information from the coordinates to return array
            BamRegion region(refID, midPoint-600, refID, midPoint+600);

            reader.SetRegion(region);

            if(!reader.SetRegion(region)){
                std::cout<<"could not set region."<<endl;
            }

            float posArray[windowSize];
            float negArray[windowSize];
            float frac_posArray[windowSize];
            float frac_negArray[windowSize];

            for (int index = 0; index < windowSize; index ++){
                posArray[index] = 0;
                negArray[index] = 0;
            }
            int posPosition;
            int negPosition;
            //if reverse strand, calculate and return the end position
            //if positive strand, return the position
            //put them in separate arrays
            while (reader.GetNextAlignment(al)){
                if (al.MapQuality>0 && al.IsReverseStrand()== true){
                    negPosition = al.GetEndPosition();
                    if (negPosition>=midPoint-halfWindowSize && negPosition <midPoint+halfWindowSize){
                        negArray[negPosition-midPoint+halfWindowSize]++;
                    }
                }else if (al.MapQuality>0){
                    posPosition = al.Position;
                    if (posPosition>=midPoint-halfWindowSize && posPosition <midPoint+halfWindowSize){
                        posArray[posPosition-midPoint+halfWindowSize]++;
                    }
                }
            }
            float posMax = 0, negMax = 0, max = 0;
            float temp;

            for (int i= 0; i<windowSize; i++){
                temp = posArray[i];
                if (temp>posMax){
                    posMax = temp;
                }
            }
            for (int i = 0; i<windowSize; i++){
                temp = negArray[i];
                if (temp>negMax){
                    negMax = temp;
                }
            }
            if (posMax>=negMax){
                max = posMax;
            }else{
                max = negMax;
            }
            for (int i = 0; i<windowSize; i++){
                frac_posArray[i] = posArray[i]/max;
                frac_negArray[i] = negArray[i]/max;
            }

            objVec[obj_i] = new ChipSeqRegion(refID, strand, midPoint, start, end, posArray, frac_posArray, negArray, frac_negArray);

            //testing
            cout<<"printing object number: "<<obj_i<<endl;
            objVec[obj_i]->PrintID();
            cout<<"printing frac pos array: "<<endl;
            objVec[obj_i]->PrintFracPosArray();
            obj_i++;
        }
        objVec[0]->PrintID();
            cout<<endl;
            objVec[0]->PrintFracPosArray();
            cout<<endl;
            objVec[1]->PrintID();
            objVec[1]->PrintFracPosArray();
            cout<<endl;
            objVec[2]->PrintID();
            objVec[2]->PrintFracPosArray();
    }


}

int main(int argc, char* argv[]) {

    string bamFileName, coordFileName;

    if (argc == 3){
        bamFileName = argv[1];
        coordFileName = argv[2];
    }else{
        std::cout << "Wrong number of arguments." <<endl;
        return 1;
    }

    if (!reader.Open(bamFileName)){
        std::cout<< "Could not open input Bam file." <<endl;
        return 1;
    }

    if (!reader.LocateIndex()){
        std::cout<<"Could not locate index file."<<endl;
        return 1;
    }

    ChipSeqLoader loader;
    loader.LoadData(bamFileName, coordFileName);



    return 0;
}

【问题讨论】:

  • 在使用调试器逐行执行代码时,您遇到了哪些异常情况?
  • 我很抱歉没有把我的帖子说得很清楚。这是我第一次发帖,我也没有太多时间格式化我的代码。非常感谢您愿意提供帮助。

标签: c++ arrays class pointers scope


【解决方案1】:

所有对象都指向同一条数据,即posArrayfrac_posArray,它们在循环中定义:如果您查看ChipSeqRegion 类构造函数,它接受2 个数组(具有相同的名称如上面引用的数组),即。 2 指向内存中数据序列的指针。构造函数中的这些指针只是简单地复制到实例字段中:

   pos_array = posArray;
   frac_positiveArray = frac_posArray;

而不是复制数组内容,因为它可能应该是:

   pos_array = new int[windowSize];
   memcpy(pos_array,posArray, sizeof(int)*windowSize); // or use std::copy_n
   frac_positiveArray =  new int[windowSize];
   memcpy(frac_positivearray,frac_posArray, sizeof(int)*windowSize); // or use std::copy_n

你可能会对类中的其他数组有同样的问题。

【讨论】:

  • 您的建议完美解决了问题!非常感谢您查看我的代码并找出我的类构造函数中的问题。一周前我开始使用指针,但我并没有太多线索知道发生了什么。我很抱歉在发布之前我没有清理我的代码。再次,我真的很感谢你的好意和帮助!
猜你喜欢
  • 2022-01-23
  • 2018-07-07
  • 2019-09-05
  • 2013-06-19
  • 1970-01-01
  • 1970-01-01
  • 2010-09-05
  • 2017-08-03
  • 1970-01-01
相关资源
最近更新 更多