很困惑当我们在c ++中重新初始化对象时会发生什么 [英] very confused about what happens when we reinitialize the object in c++

查看:164
本文介绍了很困惑当我们在c ++中重新初始化对象时会发生什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 #include< iostream> 
#include< string.h>
using namespace std;
struct integer
{
int a;
integer * next;
integer * previous;
};
integer * temp,* temp1,* temp2;
class Myinteger
{
private:


public:
integer * head;
int length
integer * tail;
Myinteger()
{
cout<<created started<<\\\
;
length = 1;
temp = new integer;
head = temp;
tail = temp;
temp-> prev = NULL;
temp-> next = NULL;
temp-> a = 0;
cout<<created ended<<\\\
;
}
Myinteger(string s)
{
cout<<constructor started string<<\\\
;
int i = 0,flag = 0;
temp = new integer;
head = temp;
temp-> prev = NULL;
if(s [0] ==' - ')
{
temp-> a = - (s [1] -48);
i = i + 2;
while(i {
temp1 = new integer;
temp-> next = temp1;
temp1-> prev = temp;
temp1-> a = s [i] -48;
temp = temp1;
i ++;
}
if(s.length()> 2)
{
temp1 = new integer;
temp-> next = temp1;
temp1-> prev = temp;
temp1-> next = NULL;
temp1-> a = s [i] -48;
tail = temp1;
if(s.length()== 3)
length = i;
else
length = i;
}
else
{
temp-> next = NULL;
tail = temp;
length = i-1;
}
}
else
{
temp-> a = s [0] -48;
i ++;
while(i {
temp1 = new integer;
temp-> next = temp1;
temp1-> prev = temp;
temp1-> a = s [i] -48;
temp = temp1;
i ++;
}
if(s.length()> 1)
{
temp1 = new integer;
temp-> next = temp1;
temp1-> prev = temp;
temp1-> a = s [i] -48;
temp1-> next = NULL;
tail = temp1;
if(flag == 0)
length = i + 1;
}
else
{
tail = temp;
temp-> next = NULL;
if(flag == 0)
length = i;
}
}
cout<<构造的结束字符串<<\ n;
}
Myinteger(const Myinteger& obj)
{
cout<<copy constructor called<<\\\

int i;
length = obj.length;
temp1 =obj.head;
temp = new integer;
head = temp;
temp-> prev = NULL;
temp-> a = temp1-> a;
temp1 = temp1-> next;
for(i = 0; i {
temp2 = new integer;
temp-> next = temp2;
temp2-> prev = temp;
temp2-> a = temp1-> a;
temp1 = temp1-> next;
temp = temp2;
}
if(obj.length> 1)
{
temp2 = new integer;
temp-> next = temp2;
temp2-> prev = temp;
temp2-> a = temp1-> a;
temp2-> next = NULL;
tail = temp2;
}
else
{
tail = temp;
temp-> next = NULL;
}
cout<<copy constructed ended<<\\\
;
}
〜Myinteger()
{
cout<<destructor started<<\\\
;
integer * del = head;
cout<<hiii;
for(int i = 0; i {
temp1 = del-> next;
cout<< del<<<< del-> a<<\\\
;
// delete del;
// del = NULL;
del = temp1;
}
// head = tail = NULL;
cout<<destructor ended<<\\\
;

}
static Myinteger parse(string s)
{
Myinteger a(s);
return a;
}
void printint()
{
temp = head;
while(temp!= NULL)
{
cout<< temp-> a;
temp = temp-> next;
}
}

Myinteger operator-(const Myinteger& obj)
{

int borrow = 0, flag1;
int a = this-> length;
int b = obj.length;
integer * tem1;
integer * tem2;
Myinteger temp = obj;
if(this-> head-> a< 0& temp.head-> a> 0)
{
this-&
Myinteger ret = * this + temp;
ret.head-> a = - (ret.head-> a);
return ret;
}
else if(this-> head-> a> 0&& temp.head-> a< 0)
{
temp.abs ;
return * this + temp;
}
else if(this-> head-> a< 0& temp.head-> a< 0)
{
this-> abs ();
temp.abs();
flag1 = -1;
}
else
{
flag = 0;
}
if(a> = b)
{
length = this-> length;
flags = 0;
tem1 = this-> tail;
temp2 = temp.tail;
integer * tem3 = this-> head;
integer * tem4 = temp.head;
if(a == b)
for(int i = a; i> 0; i--)
{
if(tem3-> a> tem4-> ; a)
{
tem1 = this-> tail;
tem2 = temp.tail;
break;
}
else if(tem3-> a< tem4-> a)
{
tem1 = temp.tail;
tem2 = this-> tail;
flag = -1;
break;
}
else
{
tem3 = tem3-> next;
tem4 = tem4-> next;
}
}
}
else
{
tem2 = this-> tail;
tem1 = temp.tail;
length = temp.length;
flag = -1;
}
char s [max(a,b)+2];
int m = max(a,b)+1;
s [m-1] ='\0';
m = m-2;
while(tem1!= NULL& tem2!= NULL)
{
if((tem1-> a-tem2-> a + borrow)<0)
{
s [m] =((tem1-> a-tem2-> a)+ 10 +借位)+48;
tem1 = tem1-> prev;
tem2 = tem2-> prev;
m--;
loan = -1;
}
else
{
s [m] =(tem1-> a-tem2-> a +借用)+48;
tem1 = tem1-> prev;
tem2 = tem2-> prev;
m--;
borrow = 0;
}
}
while(tem1!= NULL)
{
if(tem1-> a + borrow< 0)
{
s [m] =(tem1→a + borrow + 10)+48;
tem1 = tem1-> prev;
m--;
borrow = -1;
}
else
{
s [m] =(tem1-> a +借用)+48;
tem1 = tem1-> prev;
m--;
borrow = 0;
}
}
while(s [0] == 48)
{
int i = 0;
if(length == 1)
break;
while(i <= length)
{
s [i] = s [i + 1];
i ++;
}
length--;
}
if(flag == - 1)
{
int i = length;
while(i> = 0)
{
s [i + 1] = s [i]
i--;
}
s [0] =' - ';
}
string as(s);
Myinteger ret(as);
if(flag == - 1&& flag == 0)
ret.head-> a = - (ret.head-> a);
return ret;
}
Myinteger运算符+(const Myinteger& obj)
{
int flag = 0;
int carry = 0;
int length;
int a = this-> length;
int b = obj.length;
integer * tem1;
integer * tem2;
Myinteger temp = obj;
if(this-> head-> a< 0& temp.head-> a> 0)
{
this-&
Myinteger ret = * this-temp;
ret.head-> a = - (ret.head-> a);
return ret
}
else if(this-> head-> a> 0&& temp.head-> a< 0)
{
temp.abs ;
return * this-temp;
}
else if(this-> head-> a< 0& temp.head-> a< 0)
{
this-> abs ();
temp.abs();
flag = -1;
}
else
{
flag = 0;
}
if(a> = b)
{
tem1 = this-> tail;
tem2 = temp.tail;
length = this-> length;
}
else
{
tem2 = this-> tail;
tem1 = temp.tail;
length = temp.length;
}
char s [max(a,b)+2];
int m = max(a,b)+1;
s [m-1] ='\0';
m = m-2;
while(tem1!= NULL& tem2!= NULL)
{
if((tem1-> a + tem2-> a + carry)> 9)
{
s [m] =((tem1-> a + tem2-> a)-10 + carry)+48;
tem1 = tem1-> prev;
tem2 = tem2-> prev;
m--;
carry = 1;
}
else
{
s [m] =(tem1-> a + tem2-> a + carry)+48;
tem1 = tem1-> prev;
tem2 = tem2-> prev;
m--;
carry = 0;
}
}
while(tem1!= NULL)
{
if(tem1-> a + carry> 9)
{
s [m] =(tem1-> a + carry-10)+48;
tem1 = tem1-> prev;
m--;
carry = 1;
}
else
{
s [m] =(tem1-> a + carry)+48;
tem1 = tem1-> prev;
m--;
carry = 0;。
}
}
if(carry == 1)
{
int i = length;
while(i> = 0)
{
s [i + 1] = s [i]
i--;
}
s [0] = 49;
}
string as(s);
Myinteger ret(as);
if(flag == - 1)
{
ret.head-> a = - (ret.head-> a);
}
return ret;
}
void abs()
{
if(head-> a< 0)
{
head-> a = - - > a);
}
}
Myinteger运算符*(const Myinteger& obj)
{
Myinteger temp1 = obj;
Myinteger temp2(0);
temp2.​​printint();
Myinteger temp3;
// integer * tem1 = tail;
integer * tem2 = temp1.tail;
while(tem2!= NULL)
{
temp2.​​printint();
int multi = tem2-> a;
// cout<<<
//cout<<temp2.​​tail->next;
for(int i = 0; i <1; i ++)
{
// cout<< temp2.​​tail-&
temp3 = * this + temp2;
temp3.printint();
//cout<<temp2.​​head-> ;a;
temp2 = temp3;
}
tem2 = tem2-> prev;
}
//temp2.​​printint();
return temp2;
}
};
int main()
{
Myinteger obj2;
obj2 = Myinteger(10);
cout<<hiii;
obj2 = Myinteger(11);
return 0;
}

`
a在重新初始化对象obj2后立即调用析构函数10,即在打印10之前,也obj2析构函数被调用三次int程序,如果我的对象有指针应该导致错误。请帮助我解决这个问题。

解决方案

你在这里做的是称为赋值。您使用参数10创建一个新的 Myinteger 对象并将其分配给现有的 Myinteger

这里调用的是<$ c的赋值运算符。 $ c> obj2 ,如果你没有自己定义,就会自动为你分配每个内部字段。



obj2 = Myinteger(10); 创建一个 Myinteger ,并将其分配给 obj2 ,然后它在进程中破坏临时对象。因此, Myinteger(10)的临时结果在分配给 obj2 后会被销毁。 p>

对于 obj2 = Myinteger(11); 也是如此。最后,当 main 结束时 obj2 在范围外时会被破坏。



编辑:我意识到我没有解决可能是更好的方式来处理它。不知道你的具体情况,但我会详细说明一种方法。如果使用C ++ 11,可以实现move构造函数和move赋值运算符。如果正确实现这些,临时对象不会使用赋值运算符,而是通过移动赋值运算符赋值。在该运算符中,您可以有效地实现它。当隐式调用move构造函数和赋值运算符时,有一些规则,但也可以使用 std :: move 强制它。



例如,向量的移动分配可以将指针传输到底层数组,而不是复制整个数组。



另一个例子是如果你有一个网络连接的每个对象。您可以决定在目标对象中,使用原始连接并关闭临时对象上的连接。如果你有一个 connect 方法的连接,它没有被调用 - 那么你甚至还没有浪费任何资源。



注意,你仍然会得到3个构造函数和析构函数调用,但至少你会更有效地处理底层字段。


#include<iostream>
#include<string.h>
using namespace std;
struct integer
{
int a;
integer *next;
integer *prev;
};
integer *temp,*temp1,*temp2;
class Myinteger
{
private:


public:
  integer *head;
 int length;
integer *tail;
Myinteger()
{
    cout<<"constructed started"<<"\n";
    length=1;
    temp = new integer;
    head=temp;
    tail=temp;
    temp->prev=NULL;
    temp->next=NULL;
    temp->a=0;
    cout<<"constructed ended"<<"\n";
}
Myinteger (string s)
{
    cout<<"constructor started string "<<"\n";
    int i=0,flag=0;
    temp=new integer;
    head=temp;
    temp->prev=NULL;
    if(s[0]=='-')
    {
        temp->a=-(s[1]-48);
        i=i+2;
        while(i<s.length()-1)
    {
        temp1=new integer;
        temp->next=temp1;
        temp1->prev=temp;
        temp1->a=s[i]-48;
        temp=temp1;
        i++;
    }
    if(s.length()>2)
    {
        temp1=new integer;
        temp->next=temp1;
        temp1->prev=temp;
        temp1->next=NULL;
        temp1->a=s[i]-48;
        tail=temp1;
        if(s.length()==3)
            length=i;
        else
            length=i;
    }
     else
     {
         temp->next=NULL;
         tail=temp;
         length=i-1;
     }
    }
    else
    {
         temp->a=s[0]-48;
         i++;
         while(i<s.length()-1)
    {
        temp1=new integer;
        temp->next=temp1;
        temp1->prev=temp;
        temp1->a=s[i]-48;
        temp=temp1;
        i++;
    }
    if(s.length()>1)
    {
        temp1=new integer;
        temp->next=temp1;
        temp1->prev=temp;
        temp1->a=s[i]-48;
        temp1->next=NULL;
        tail=temp1;
        if(flag==0)
        length=i+1;
    }
    else
    {
        tail=temp;
        temp->next=NULL;
        if(flag==0)
        length=i;
    }
    }
    cout<<"constructed ended string"<<"\n";
}
Myinteger(const Myinteger& obj)
{
    cout<<"copy constructor called"<<"\n";
    int i;
    length=obj.length;
    temp1=obj.head;
    temp=new integer;
    head=temp;
    temp->prev=NULL;
    temp->a=temp1->a;
    temp1=temp1->next;
    for(i=0;i<obj.length-2;i++)
    {
        temp2=new integer;
        temp->next=temp2;
        temp2->prev=temp;
        temp2->a=temp1->a;
        temp1=temp1->next;
        temp=temp2;
    }
    if(obj.length>1)
    {
        temp2=new integer;
        temp->next=temp2;
        temp2->prev=temp;
        temp2->a=temp1->a;
        temp2->next=NULL;
        tail=temp2;
    }
    else
    {
        tail=temp;
        temp->next=NULL;
    }
    cout<<"copy constructed ended"<<"\n";
}
~Myinteger()
{
    cout<<"destructor started"<<"\n";
    integer *del=head;
    cout<<"hiii";
    for(int i=0;i<length;i++)
    {
        temp1=del->next;
        cout<<del<<" "<<del->a<<"\n";
        //delete del;
        //del=NULL;
        del=temp1;
    }
    //head=tail=NULL;
    cout<<"destructor ended"<<"\n";

}
static Myinteger parse(string s)
{
     Myinteger a(s);
     return a;
}
void printint()
{
     temp=head;
     while(temp!=NULL)
     {
         cout<<temp->a;
         temp=temp->next;
     }
}

Myinteger operator-( const Myinteger &obj)
{

  int borrow=0,flag,length,flag1;
  int a=this->length;
  int b=obj.length;
  integer *tem1;
  integer *tem2;
  Myinteger temp=obj;
  if(this->head->a<0&&temp.head->a>0)
  {
      this->abs();
      Myinteger ret = *this+temp;
      ret.head->a=-(ret.head->a);
      return ret;
  }
  else if(this->head->a>0&&temp.head->a<0)
  {
      temp.abs();
      return *this+temp;
  }
  else if(this->head->a<0&&temp.head->a<0)
  {
      this->abs();
      temp.abs();
      flag1=-1;
  }
  else
  {
      flag=0;
  }
  if(a>=b)
  {
       length=this->length;
       flag=0;
       tem1=this->tail;
       tem2=temp.tail;
       integer *tem3=this->head;
       integer *tem4=temp.head;
       if(a==b)
       for(int i=a;i>0;i--)
       {
           if(tem3->a>tem4->a)
           {
               tem1=this->tail;
               tem2=temp.tail;
               break;
           }
           else if(tem3->a<tem4->a)
           {
               tem1=temp.tail;
               tem2=this->tail;
               flag=-1;
               break;
           }
           else
           {
               tem3=tem3->next;
               tem4=tem4->next;
           }
       }
  }
  else
  {
       tem2=this->tail;
       tem1=temp.tail;
       length=temp.length;
       flag=-1;
  }
  char s[max(a,b)+2];
  int m=max(a,b)+1;
  s[m-1]='\0';
  m=m-2;
  while(tem1!=NULL&&tem2!=NULL)
  {
      if((tem1->a-tem2->a+borrow)<0)
      {
          s[m]=((tem1->a-tem2->a)+10+borrow)+48;
          tem1=tem1->prev;
          tem2=tem2->prev;
          m--;
          borrow=-1;
      }
      else
     {
        s[m]=(tem1->a-tem2->a+borrow)+48;
        tem1=tem1->prev;
        tem2=tem2->prev;
        m--;
        borrow=0;
     }
  }
      while(tem1!=NULL)
      {
          if(tem1->a+borrow<0)
          {
              s[m]=(tem1->a+borrow+10)+48;
              tem1=tem1->prev;
              m--;
              borrow=-1;
          }
          else
          {
              s[m]=(tem1->a+borrow)+48;
              tem1=tem1->prev;
              m--;
              borrow=0;
          }
      }
      while(s[0]==48)
      {
          int i=0;
          if(length==1)
            break;
          while(i<=length)
          {
              s[i]=s[i+1];
              i++;
          }
          length--;
      }
      if(flag==-1)
      {
          int i=length;
          while(i>=0)
          {
              s[i+1]=s[i];
              i--;
          }
          s[0]='-';
      }
  string as(s);
  Myinteger ret(as);
  if(flag==-1&&flag==0)
    ret.head->a=-(ret.head->a);
  return ret;
 }
 Myinteger operator+( const Myinteger &obj)
 {
  int flag=0;
  int carry=0;
  int length;
  int a=this->length;
  int b=obj.length;
  integer *tem1;
  integer *tem2;
   Myinteger temp=obj;
  if(this->head->a<0&&temp.head->a>0)
  {
    this->abs();
    Myinteger ret =*this-temp;
    ret.head->a=-(ret.head->a);
    return ret;
  }
  else if(this->head->a>0&&temp.head->a<0)
  {
      temp.abs();
      return *this-temp;
  }
  else if(this->head->a<0&&temp.head->a<0)
  {
      this->abs();
      temp.abs();
      flag=-1;
  }
  else
  {
      flag=0;
  }
  if(a>=b)
  {
       tem1=this->tail;
       tem2=temp.tail;
       length=this->length;
  }
  else
  {
       tem2=this->tail;
       tem1=temp.tail;
       length=temp.length;
  }
  char s[max(a,b)+2];
  int m=max(a,b)+1;
  s[m-1]='\0';
  m=m-2;
  while(tem1!=NULL&&tem2!=NULL)
  {
      if((tem1->a+tem2->a+carry)>9)
      {
          s[m]=((tem1->a+tem2->a)-10+carry)+48;
          tem1=tem1->prev;
          tem2=tem2->prev;
          m--;
          carry=1;
      }
      else
     {
        s[m]=(tem1->a+tem2->a+carry)+48;
        tem1=tem1->prev;
        tem2=tem2->prev;
        m--;
        carry=0;
     }
  }
      while(tem1!=NULL)
      {
          if(tem1->a+carry>9)
          {
              s[m]=(tem1->a+carry-10)+48;
              tem1=tem1->prev;
              m--;
              carry=1;
          }
          else
          {
              s[m]=(tem1->a+carry)+48;
              tem1=tem1->prev;
              m--;
              carry=0;
          }
      }
      if(carry==1)
      {
         int i=length;
          while(i>=0)
          {
             s[i+1]=s[i];
             i--;
          }
          s[0]=49;
      }
  string as(s);
  Myinteger ret(as);
  if(flag==-1)
  {
      ret.head->a=-(ret.head->a);
  }
  return ret;
  }
   void abs()
   {
 if(head->a<0)
 {
     head->a=-(head->a);
 }
   }
   Myinteger operator *(const Myinteger &obj)
  {
  Myinteger temp1=obj;
  Myinteger temp2("0");
  temp2.printint();
  Myinteger temp3;
  //integer *tem1=tail;
  integer *tem2=temp1.tail;
  while(tem2!=NULL)
  {
      temp2.printint();
      int multi=tem2->a;
      //cout<<multi;
      //cout<<temp2.tail->next;
      for(int i=0;i<1;i++)
      {
         // cout<<temp2.tail->next;
          temp3=*this+temp2;
          temp3.printint();
          //cout<<temp2.head->a;
          temp2=temp3;
      }
      tem2=tem2->prev;
  }
  //temp2.printint();
  return temp2;
  }
  };
  int main()
 {
Myinteger obj2;
obj2=Myinteger("10");
cout<<"hiii";
obj2=Myinteger("11");
return 0;
}

` a destructor is being called immediately after reinitializing the object obj2 with "10",ie before printing 10,also obj2 destructor is called three times int the program which should lead to error if my object has pointers . please ,help me to solve this issue

解决方案

What you are doing here is called assignment. You create a new Myinteger object with parameter "10" and assign it to an existing Myinteger object, obj2.

What's called here is the assignment operator of obj2, which if you didn't define yourself, is automatically defined for you by assigning each of the internal fields.

So obj2 = Myinteger("10"); creates a Myinteger and assigns it to obj2, and after that it destructs the temporary object in the process. So, the temporary result of Myinteger("10") is destructed after it has been assigned to obj2.

The same goes for obj2 = Myinteger("11");. Finally, obj2 gets destructed when it goes out of scope, at the end of main.

EDIT: I realized I didn't address what might be the better way to deal with it. Not sure about your specific case, but I'll elaborate on one approach. If you use C++11, you can implement the move constructor and move assignment operator. If you implement those correctly, temporary objects will not assigned using the assignment operator, but by the move assignment operator. In that operator, you can implement it efficiently. There are rules when the move constructor and assignment operator are called implicitly, but it's also possible to use std::move to force it.

For example, a move assignment of a vector can just transfer the pointer to the underlying array instead of copying the entire array.

Another example is if you have a network connection for each object. You can decide that in the target object, you use the original connection and close the one on the temporary object. If you have an connect method for the connection and it was not called - then you even haven't wasted any resources yet.

Note that you'll still get 3 constructor and destructor calls, but at least you'll be more efficient dealing with the underlying fields.

这篇关于很困惑当我们在c ++中重新初始化对象时会发生什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆