在C ++中访问对象属性

时间:2014-10-30 02:42:24

标签: c++ arrays class pointers scope

我对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;
}

1 个答案:

答案 0 :(得分:0)

所有对象都指向同一条数据,即循环中定义的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

您可能会遇到与该类中其他数组相同的问题。