2017-04-13 54 views
1

在我的理解中,在通常情况下,数组在编译时被分配内存,但是当数组是一个成员变量时会发生什么,在编译过程中几乎没有任何东西可以分配内存。是否在创建该类的实例时被隐式动态分配?如何将内存分配给具有数组成员的类的实例?

class Arr{ 
    public: 
    int arr[10]; 
}; 

Arr doSomething(Arr &arg){ 
    return arg; //copy of arg created; 'copy=new int[10]' at this point? 
} 

int main(){ 
    Arr temp; 
    doSomething(temp); 

    //if returned object's array was dynamically initialized 
    //will it result the array in temp being released twice? 
} 

UPD。在我的情况下,当我尝试将B> A的A-B分解时,情况会上升。在这些情况下,我可以访问数组来读取它,但修改它的值会导致垃圾。此外,在main的最终输出是好的。下面是完整的代码:

#include <iostream> 

using namespace std; 

const int MAX_ARRAY_SIZE=256; 

char* getOperatorIndex(char* equationString); 
bool isOperator(char characterDec); 
int* toIntArray(char* firstInA, char* lastInA, int* firstInB); 

class Number{ 
    int* firstInNumber; 
    int* lastInNumber; 
    int number[MAX_ARRAY_SIZE]; 

    public: 
    Number(); 
    ~Number(); 
    bool operator<(Number& b); 
    int& operator[](int index); 
    Number operator-(Number& b); 
    void print(); 
    int length(){return lastInNumber-firstInNumber;} 
    int*& lastPtr(){return lastInNumber;} 
    int*& firstPtr(){return firstInNumber;} 
}; 

Number::Number(){ 
    firstInNumber=number; 
    lastInNumber=number; 
} 

Number::~Number(){ 
    cout<<"number destroyed"<<endl; 
} 

int& Number::operator[](int index){ 
    return number[index]; 
} 

bool Number::operator<(Number& b){ 
    if(length()>b.length())return false; 
    if(length()<b.length())return true; 

    for(int a=0;a<length();++a){ 
     if(number[a]>b[a])return false; 
     if(number[a]<b[a])return true; 
    } 
    return false; 

} 

void Number::print(){ 
    for(int a=0; a<=length(); ++a){ 
     cout<<number[a]; 
    } 
    cout<<endl; 
} 

Number Number::operator-(Number& b){ 

    Number result; 

    if(*this < b) 
    { 
     result=b-*this; 
     cout<<*result.lastPtr()<<endl; 
     result.print(); 
     *result.lastPtr()*=-1; // GARBAGE HERE 
     cout<<*result.lastPtr()<<endl; 
     return result; 
    } 

    result[0]=0; 

    for(int q=0; q<=length(); ++q) 
    { 

     if(b.length()-q >= 0) 
     { 
      result[q]+=(*this)[length()-q]-b[b.length()-q]; 

      if(result[q] < 0) 
      { 
       result[q]+=10; 
       result[q+1]=-1; 

      } 
      else 
      { 
       result[q+1]=0; 
      } 

     } 
     else 
     { 
      result[q]+=(*this)[length()-q]; 

     } 

    ++result.lastPtr(); 
    } 

    do{ 
     --result.lastPtr(); 
    }while(!*result.lastPtr()); 

    return result; 
} 

int main(){ 
    char equationArray[MAX_ARRAY_SIZE*2+1]; // operandA(<=256) operator(1) operandB(<=256) 
    Number a,b; 

    cin>>equationArray; 
    char* operatorPtr=getOperatorIndex(equationArray); 

    a.lastPtr()=toIntArray(equationArray, operatorPtr, a.firstPtr()); 
    b.lastPtr()=toIntArray(operatorPtr+1, operatorPtr+strlen(operatorPtr), b.firstPtr()); 

    a.print(); 
    b.print(); 

    Number c; 
    switch(*operatorPtr){ 
     case '-': 
      c=a-b; 
      break; 
    } 
    c.print(); 

} 


char* getOperatorIndex(char* equationString){ 
    while(!isOperator(*++equationString)); 
    return equationString; 
} 

bool isOperator(char characterDec){ 
    if(characterDec>='*' & characterDec<='/')return true; 
    return false; 
} 


int* toIntArray(char* firstInA, char* lastInA, int* firstInB){ 
    while(lastInA-firstInA>0){ 
     *firstInB=*firstInA-'0'; 
     ++firstInB; 
     ++firstInA; 
    } 
    return --firstInB; 
} 
+0

您是否尝试过运行此程序?说实话,我也不确定如果你复制构建一个具有动态分配数组的东西会发生什么。 –

+0

你能澄清你在问什么 - 你为什么想象一个数组成员变量会不同于一个非数组成员变量? –

+0

我们可以看到你的类定义是一个typedef(如果它没有静态成员变量),并且类型不分配内存。 – olivecoder

回答

3

一类的所有数据成员具有相同存储时间作为创建类的对象。因此,在:

int main(){ 
    Arr temp; 
    doSomething(temp); 
} 

它的类型的数据成员temp.arrint[10];还具有自动存储持续时间 ..(或什么是不适当称为 “堆栈对象”)


Arr doSomething(Arr &arg){ 
    return arg; //copy of arg created; 'copy=new int[10]' at this point? 
} 

不,这里没有堆分配。而不是隐式拷贝构造函数的成员智能副本。请参阅How are C++ array members handled in copy control functions?

+0

如果有一个指针作为成员变量,那会指向数组中的最后一个元素呢?当临时对象被释放时,它会导致数组中的指针变量被释放吗? –

+0

@MikeMike,如果有指针,那么我们可以假设这个类的对象管理一个资源。在这种情况下,你应该**确定并实现你的特殊成员函数。这是因为,隐式拷贝构造函数只会复制指针的值,指针仍然会指向** old **对象数组的最后一个元素。现在的问题是新复制的指针数据成员不是指向它自己的对象的数组的末尾,而是另一个对象。 – WhiZTiM

+0

@Mike Mike - 编号当包含指针的临时对象被释放或以其他方式销毁时,指针默认不受影响。可以为对象的类编写一个析构函数,该函数明确地用指针做某事,但这需要程序员有意识地采取行动。 C++不是垃圾收集。 – Peter

相关问题