2016-08-07 12 views
0

Dies war eine Hausaufgabe aus dem letzten Jahr, die ich beschloss, aufzuschlagen und durchzuschauen. Ich habe den Debugger durchlaufen und festgestellt, dass der Destruktor am Ende einer Zuweisungsoperation aufgerufen wurde (überladene Zuweisung). Kann mir jemand sagen, warum es heißt? Ich habe den vollständigen Code bereitgestellt, damit er in einem Compiler ausgeführt werden kann (was die Beantwortung der Frage erleichtern kann), aber meine Frage betrifft nur einen sehr kleinen Teil des Codes. In der Treiberdatei gibt es eine Funktion namens void TestCopyConstructor(). In dieser Funktion gibt es eine Zuweisungsoperation X = "0.12345";. Dies ruft eine der überladenen Zuweisungsoperatorfunktionen MyFloat MyFloat::operator= (const char *Input) auf. Diese Funktion läuft und am Ende davon heißt ein Kopierkonstruktor MyFloat MyFloat::MyFloat(const MyFloat & RHS). Nach dieser Funktion kehrt es zurück zu void TestCopyConstructor(), wo der Destruktor aufgerufen wird. Ich versuche zu verstehen, warum dieser Destruktor aufgerufen wird. Ich weiß, dass das eine Menge Code ist, weshalb ich versucht habe, durch den bestimmten Bereich zu gehen, in dem ich verwirrt bin, da ich nicht sicher war, wie ich eine abgespeckte, funktionierende Version dieses Codes machen könnte.Versuchen zu verstehen, warum der Klassenzerstörer nach dem Zuweisungsoperator aufgerufen wird

DRIVER:

#include "MyFloatD.cpp" // Name of your class definition. Use pathname 
// if file is not in current working directory. 
#include <iostream> 
#include <iomanip> 
#include <ctype.h> 
#include <new> 
using namespace std; 

void DisplayTestingOptions(); 
void GetChoice(char& Ch); 

void TestInputOperator(); 
void TestAssignment(); 
void TestCopyConstructor(); 
void TestComparison(); 
void TestPlus(); 
void TestDestructor(); 

float CPU_Seconds(); 

//============================== main ================================= 

int main() 
{ 
    char Choice; 

    do 
    { 

     DisplayTestingOptions(); 

     GetChoice(Choice); 

     switch (Choice) 
     { 
      case '1': TestCopyConstructor(); 
       break; 
      case '2': TestAssignment(); 
       break; 
      case '3': TestInputOperator(); 
       break; 
      case '4': TestPlus(); 
       break; 
      case '5': TestComparison(); 
       break; 
      case '6': TestDestructor(); 
       break; 
      case 'Q':  ;       // Exit 
     }; 
    } 
    while (Choice != 'Q'); 

    return 0; 
} 

/*********************** SpaceBarToContinue ************************** 

Displays "Spacebar to continue" and returns 1 iff Spacebar pressed. 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ 
int SpaceBarToContinue(const char* Message = " Spacebar continues this test") 
{ 
    char Ch; 

    cout << "\n------------------------------------------" 
    << Message; 
    Ch = cin.get(); 

    return (Ch == ' '); 
} 

/*********************** DisplayTestingOptions ************************ 

Displays a menu of choices. 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ 
void DisplayTestingOptions() 
{ 
    const char* TAB = "  "; // Provides menu spacing 

    cout << "\n\n"; 
    cout << "\n----------------------------------" 
    "------------------------------------\n\n"; 

    cout << TAB << "1) Test copy constructor  "; 

    cout << TAB << "2) Test assignment operator \n"; 

    cout << TAB << "3) Test >> input function "; 

    cout << TAB << "4) Test + operator  \n"; 

    cout << TAB << "5) Test == operator   "; 

    cout << TAB << "6) Test destructor  \n"; 

    cout << TAB << "Q) Quit program\n\n"; 

    cout << "Choice? "; 

} 

/*********************** GetChoice ************************************ 

Reads a char from the keyboard, provides a redirectable echo and 
upcases the char. 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ 
void GetChoice(char& Ch) 
{ 
    cin >> Ch; 
    Ch = toupper(Ch); 

} 

/********************* TestInputOperator ****************************** 

Allows testing of the member functions ">>" of MyFloat. 

The insertion operator << is assumed to be correct. 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ 
void TestInputOperator() 
{ 
    MyFloat X; 

    cout << "\n\n>>>>>>>>>>>>> Testing input operator >>>>>>>>>>>>>>>>>\n"; 
    do 
    { 
     cout << "\nEnter MyFloat ==> "; 
     cin >> X; 

     cout << "\nAfter the read, X = '" << X << "'\n\n"; 
    } 
    while (SpaceBarToContinue()); 

    if (cin.peek() != EOF) 
     cin.ignore(1000, '\n'); 

} 


/********************* TestAssignment ********************************* 

Allows testing of the member function "=" of MyFloat. If a deep copy 
assignment operator has not been written, the code below will give 
unexpected output. 

This routine assumes that input and output functions for MyFloats 
have been written and debugged. 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ 
void TestAssignment() 
{ 
    MyFloat X(10), Y(10); 

    cout << "\n\n------------ Testing '=' for MyFloats --------------------\n\n"; 

    X = "0.1234567890"; 

    Y = X;    // This must be a deep copy 

    X = "0.0";   // Or this will change Y! 

    cout << "\nAfter the assignments, X = \"0.1234567890\", Y = X, and X = 0.0, " 
    << "Y = " << Y << endl; 

} 


/********************* TestPlus *************************************** 

Allows testing of the member function operator+. At the present time, 
it allows testing only of addition for MyFloats that have the default 
length. 

NOTE: Calls two of the copy constructors. The copy constructor also 
needs to be working correctly for + to work. 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ 
void TestPlus() 
{ 
    MyFloat X(12), Y, Sum; 


    cout << "\n\n++++++++++++++++ Testing \"+\" for MyFloat ++++++++++++++++\n" 
    << "     (Do not use leading zero)\n"; 
    do 
    { 
     cout << "\nEnter X ==> "; 
     cin >> X; 
     cin.ignore(1000, '\n');   // Discard all chars in input stream. 

     cout << "\nEnter Y ==> + "; 
     cin >> Y; 

     cin.ignore(1000, '\n');   // Discard all chars in input stream. 
     cout << "    "; 

     for (int k = 1; k <= X.Digits() + 3 || k <= Y.Digits() + 3 ; ++k) 
      cout << '-'; 

     cout << "\n    "; 

     Sum = X + Y; 

     cout << Sum << "\n\n"; 

    } 
    while (SpaceBarToContinue()); 
} 


/********************* TestCopyConstructor **************************** 

Allows testing of the copy constructor that is called automatically 
under certain circumstances. 

Note that that the default constructor and the overloaded "=" operator 
must also be working properly. 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ 
void TestCopyConstructor() 
{ 
    MyFloat X;  // Default constructor called 

    X = "0.12345"; // Overloaded "=" operator called 

    MyFloat Y = X; // Copy constructor called 

    X = "0.0"; 

    cout << "\n\n============ Testing copy constructor ================\n\n"; 
    cout << "NOTE: This function also calls default constructor and '='operator. \n\n\n"; 

    cout << "After 'X = 0.0', Y = " << Y << "\nNote that Y should be 0.12345\n"; 

} 

/********************* TestComparison ********************************* 

Allows testing of the member function operator+. At the present time, 
it allows testing only of addition for MyFloats that have the default 
length. 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ 
void TestComparison() 
{ 
    MyFloat A, B, Sum; 


    cout << "\n\n== == == == == Testing \"== \" for MyFloat == == == == == \n\n"; 

    cout << "MyFloat variables have maximum length of " << A.MaxDigits() << endl; 
    do 
    { 
     cout << "\nEnter A ==> "; 
     cin >> A; 
     cout << "\nEnter B ==> "; 
     cin >> B; 

     cout << "\n (A == B) is " << ((A == B) ? "TRUE " : "FALSE ") << endl; 


    } 
    while (SpaceBarToContinue()); 
} 

/********************* TestDestructor ********************************** 

Tests to see if the class destructor has been correctly written. If not 
this program may crash. 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ 
void TestDestructor() 
{ 

    const unsigned long REPETITIONS = 70000; 

    for (unsigned long N = 1; N <= REPETITIONS; ++N) 
    { 
     MyFloat X(10000); // Create 1000 digit MyFloat 
    }     // X goes out of scope at each repetition 

    // If the destructor is not correct, each repetition of the 
    // loop above will caused some memory leak and the call to 
    // new below will fail. 

    int* A = new int[120]; 

    if (A == NULL) 
     cout << "\n\nYour memory has leaked away!\n"; 
    else 
    { 
     delete [] A; 
     cout << "\n\n~~~~~~~~~~~~~~ destructor is OK! ~~~~~~~~~~~~~~~\n"; 
    } 
    SpaceBarToContinue(" spacebar to continue"); 
} 

UND die Klasse selbst:

/****************************************************************** 
----------------------Class Breakdown---------------------------- 

Data Members: 

-enum (Default Size) sets the size of the MyFloat to 10 by default if no 
      size is specified 

-Char *Number points at array being dynamically allocated in memory 

-NumberOfDigits represents the length of the current float 

-MaxNumberOfDigits represents the longest length that that particular 
      object can hold 

Member Functions: 

-MyFloat(const MyFloat & RHS) copy constructor allows usuer to initialize 
     new object with another object, by placing it in the parameter list 

-MyFloat() is default constructor, initializes objects at MaxSize of 10 

-MyFloat(unsigned int Input) standard constructor allows user to create 
     MyFloat of any size by placing a numerical value in the parameter list 

-int Digits() returns size of number currently stored in object 

-int MaxDigits() returns the maximum size allowed in current object 

-MyFloat operator= (const char *Input) overloaded assignemnt operator 
     to work with setting an object equal to a literal string (X="0.004") 

-MyFloat operator= (const MyFloat &X) overloaded assignent operator to work 
     with setting an object equal to another object 

-int operator== (const MyFloat &x) overloaded comparison operator 

-MyFloat operator+ (MyFloat X) overloaded addition operator 

-int operator> (MyFloat x) overloaded greater than comparison operator 

-friend ostream& operator<< (ostream &Out, const MyFloat & X) 
     overloaded insertion operator, so user can cout << X 

-friend istream& operator>> (istream &In, MyFloat & X) 
     overloaded extraction operator, so user can cin >> X 
********************************************************************/ 
#include <iostream> 
#include <ctype.h> 

using namespace std; 

class MyFloat 
{ 
    enum {DefaultSizeTen=10}; 
    char *Number; 

    int NumberOfDigits; 
    int MaxNumberOfDigits; 

public: 

    ~MyFloat(); 

    MyFloat(const MyFloat & RHS); 
    MyFloat(); 
    MyFloat(unsigned int Input); 

    int Digits(); 
    int MaxDigits(); 

    MyFloat operator= (const char *Input); 
    MyFloat operator= (const MyFloat &X); 

    int operator== (const MyFloat &x); 

    MyFloat operator+ (const MyFloat &X); 
    int operator> (const MyFloat &x); 

    friend ostream& operator<< (ostream &Out, const MyFloat & X); 
    friend istream& operator>> (istream &In, MyFloat & X); 

}; 

/********************* MyFloat Destructor *************************** 
Action: Deletes the memory being pointed to by the pointer Number; 
Parameters: 
    IN: none 
    OUT: none 
Returns: none 
Preconditions: Number has to be pointing at memory, or else error 
     occur 
*******************************************************************/ 

MyFloat::~MyFloat() 
{ 
    delete Number; 
} 

/********************* MyFloat Copy Constructor ********************* 
Action: Initializes an object of MyFloat to be equal to any object being 
     passed in via parameter list 
Parameters: 
    IN: none 
    OUT: const MyFloat & RHS - float being getting copied 
Returns: none 
Preconditions: must be of same data type - MyFloat 
*******************************************************************/ 

MyFloat::MyFloat(const MyFloat & RHS) 
{ 
    MaxNumberOfDigits=RHS.MaxNumberOfDigits; 
    NumberOfDigits=RHS.NumberOfDigits; 

    Number = new (nothrow) char[RHS.NumberOfDigits+1]; //+1 for overflow 

    if (Number != NULL) 
    { 
     for (int i=0; i<=RHS.NumberOfDigits-1; ++i) 
     { 
      Number[i]=RHS.Number[i]; 
     } 
    } 

    else 
     NumberOfDigits=0; 
} 

/********************* MyFloat Default Constructor ******************* 
Action: Sets NumberOfDigits to 10 and places 0 in all elements of array 
     being pointed to by *Number 
Parameters: 
    IN: none 
    OUT: none 
Returns: none 
Preconditions: none 
*******************************************************************/ 

MyFloat::MyFloat() 
{ 
    MaxNumberOfDigits=DefaultSizeTen;//set MaxNumberOfDigits to default size of 10 
    NumberOfDigits = 0; 

    Number = new (nothrow) char[MaxNumberOfDigits+1]; //+1 for overflow 

    if (Number != NULL) 
    { 
     for (int i=0; i<=MaxNumberOfDigits; ++i) 
     { 
      Number[i]=0; 
     } 
    } 
} 

/********************* MyFloat Standard Constructor ******************* 
Action: Sets NumberOfDigits to be equal to whatever user places inside of 
     the paramter list 
Parameters: 
    IN: unsigned int Input 
    OUT: none 
Returns: none 
Preconditions: Input must be int and not negative 
*******************************************************************/ 

MyFloat::MyFloat(unsigned int Input)//Constructor that zeros out Number[] and NumberOfDigits 
{ 
    MaxNumberOfDigits=Input; 
    NumberOfDigits=0; 

    Number = new (nothrow) char[MaxNumberOfDigits+1]; 

    if (Number != NULL) 
    { 
     for (int i=0; i<=MaxNumberOfDigits; ++i) 
     { 
      Number[i]=0; 
     } 
    } 
} 

/********************* Digits() ******************************** 
Action: Simply returns NumberOfDigits to main 
Parameters: 
    IN: none 
    OUT: none 
Returns: returns the NumberOfDigits 
Preconditions: none 
*******************************************************************/ 

int MyFloat::Digits() 
{ 
    return NumberOfDigits; 
} 

/********************* MaxDigits() ******************************** 
Action: Returns MAXDIGIT to main 
Parameters: 
    IN: none 
    OUT: none 
Returns: returns MAXDIGIT 
Preconditions: none 
*******************************************************************/ 

int MyFloat::MaxDigits()//Return MAXDIGIT or MaxNumberOfDigits? 
{ 
    return MaxNumberOfDigits; 
} 

/********************* operator=() ******************************** 
Action: Overloads the assignment operator to allow a string to be stored 
    in the MyFloat data type, by dynamically allocating memory for a new 
    array 
Parameters: 
    IN: none 
    OUT: Const char *Input, which points to the string being assigned to MyFloat 
     data type 
Returns: *this 

Preconditions: Assumes incoming string was typed with leading '0' and '.', 
    these are skipped when storing the string in the MyFloat data type 
    Number isn't stored if decimal isn't present 

*Modified overloaded = function from solution set, since my original 
function had some errors 
*******************************************************************/ 

MyFloat MyFloat::operator= (const char *Input) 
{ 
    int CounterForInput = 0, CounterForNumber = 0, Length = 0, Temp = 0; 

    NumberOfDigits = 0; 


    /* SKIP PAST LEADING WHITESPACE, LEADING 0s, and Decimal */ 


    while ((isspace(Input[CounterForInput]) || Input[CounterForInput] == '0') && Input[CounterForInput] != 0 ) // Skip blanks and zeros 
     ++CounterForInput; 

    if (Input[CounterForInput] != '.') 
     return *this;     // Error, no decimal point 

    ++CounterForInput;       // Move to char after '.' 


    /* CHECK TO SEE IF POINTER IS POINTING AT AN ARRAY WITH ENOUGH ROOM FOR COPY */ 


    Temp = CounterForInput; 

    while (isdigit(Input[Temp])) // get length of incoming float without affecting CounterForInput 
    { 
     ++Length; 
     ++Temp; 
    } 

    if (MaxNumberOfDigits<Length) 
    { 
     delete Number; 
     Number = new (nothrow) char[Length+1]; 

     if (Number == NULL) 
     { 
      NumberOfDigits = 0; 
      return *this; 
     } 
    } 


    /* ASSIGN INPUT TO ARRAY BEING POINTED AT BY NUMBER */ 


    while (CounterForNumber <= MaxNumberOfDigits && isdigit(Input[CounterForInput])) // Copy rest of string 
     Number[CounterForNumber++] = Input[CounterForInput++] - '0'; 

    NumberOfDigits = CounterForNumber; 

    while (CounterForNumber < MaxNumberOfDigits)  // Pad with trailing zeros 
     Number[++CounterForNumber] = 0; 

    return *this; 
} 

/********************* operator=() ******************************** 
Action: Another Overloaded assignment operator to allow a MyFloat to be 
    copied to another MyFloat, by dynamically allocating memory for a new 
    array 
Parameters: 
    IN: none 
    OUT: Const MyFloat &X 
Returns: *this 
Preconditions: none 
*******************************************************************/ 

MyFloat MyFloat::operator= (const MyFloat &X) 
{ 
    if (MaxNumberOfDigits<X.MaxNumberOfDigits) 
    { 
     delete Number; 

     Number = new (nothrow) char [X.MaxNumberOfDigits+1]; 

     if (Number == NULL) 
     { 
      NumberOfDigits=0; 
      return *this; 
     } 
    } 

    NumberOfDigits = X.NumberOfDigits; 
    MaxNumberOfDigits = X.MaxNumberOfDigits; 

    for (int i=0; i<=MaxNumberOfDigits; i++) 
    { 
     Number[i] = X.Number[i]; 
    } 

    return *this; 
} 

/********************* operator==() ******************************** 
Action: Overloads the comparison operator to compare data members of 
     two different objects of MyFloat 
Parameters: 
    IN: none 
    OUT: const MyFloat &x, which contains data members holding one float 
Returns: 1 if both MyFloat numbers are equal, 0 if they are different 
Preconditions: none 
*******************************************************************/ 

int MyFloat::operator== (const MyFloat &x) 
{ 
    int Counter; 

    if (NumberOfDigits>x.NumberOfDigits) 
     Counter = NumberOfDigits; 

    else 
     Counter = x.NumberOfDigits; 

    for (int i=0; i<=Counter || Number[i]; ++i) 
    { 
     if (x.Number[i]!=Number[i]) 
      return 0; 
    } 
    return 1; 
} 

/********************* operator+() ******************************** 
Action: Overloads the addition operator to allow it to add two MyFloats 
     together 
Parameters: 
    IN: none 
    OUT: MyFloat x, which contains data members holding one float 
Returns: MyFloat Storage back to main driver 
Preconditions: none 
*******************************************************************/ 

MyFloat MyFloat::operator+ (const MyFloat &X) 
{ 
    int Carry=0; 
    int Integer=0; 
    int DifferenceInLength=0; 
    int ForLoopCounter=0; 
    MyFloat Storage; 

    if (NumberOfDigits > X.NumberOfDigits) 
    { 
     Storage = *this; 
     //just copy larger float over to storage so it is large enough to hold new number 
     //new number will use the same ending numbers as the longest number as well 

     DifferenceInLength = NumberOfDigits - X.NumberOfDigits; 
     //Get the difference between the lengths of the two numbers, will be used in next for loop 

     ForLoopCounter=NumberOfDigits - DifferenceInLength; 
    } 

    else 
    { 
     Storage = X; 
     DifferenceInLength = X.NumberOfDigits - NumberOfDigits; 
     ForLoopCounter=X.NumberOfDigits - DifferenceInLength; 
    } 

    for (int i=ForLoopCounter-1; i>=0; --i) //- 1 to work with Array style counting 
    { 
     Integer = ((X.Number[i]) + (Number[i]) + (Carry)); 

     Carry = 0; 

     if (Integer>=10) 
     { 
      Carry = Integer/10; 
      Integer %= 10; 
     } 

     Storage.Number[i] = Integer; 

     Integer = 0; 
    } 

    if (NumberOfDigits>X.NumberOfDigits) 
     Storage.NumberOfDigits = (NumberOfDigits); 

    else 
     Storage.NumberOfDigits = X.NumberOfDigits;//Storage.NumberOfDigits will be equal to the larger NumberOfDigits of the two floats being added 

    return Storage; 
} 

/********************* operator>() ******************************** 
Action: Overloads the greater than operator to allow two MyFloats to be 
    compared 
Parameters: 
    IN: none 
    OUT: const MyFloat &x, which contains data members holding one float 
Returns: 0 if false, 1 if true (if calling object is greater than object 
    being passed in) 

Preconditions: none 
*******************************************************************/ 

int MyFloat::operator> (const MyFloat &x) 
{ 
    for (int i=0; i<=MaxNumberOfDigits; ++i) 
    { 
     if (Number[i]<x.Number[i]) 
      return 0; 
     else if (Number[i]>x.Number[i]) 
      return 1; 
    } 
    return 1; 
} 

/********************* operator<<() ******************************** 
Action: Overloads << operator to allow it to work on custom MyFloat 
     data type 
Parameters: 
    IN: none 
    OUT: ostream &Out, const MyFloat & x 
Returns: Reference to ostream 
Preconditions: none 
*******************************************************************/ 

ostream & operator<< (ostream &Out, const MyFloat & X) 
{ 
    Out << "0."; 

    if (X.NumberOfDigits != 0) 
    { 
     for (int j=0; j<=X.NumberOfDigits-1; ++j) 
     { 
      Out << (int) X.Number[j]; 
     } 
    } 

    else 
     Out << "?"; 

    return Out; 
} 

/********************* operator>>() ******************************** 
Action: Reads and stores the float typed in by the user using certain 
    conditions. Skips all leading whitespace and 0s, then stores any 
    numbers after that. 
Parameters: 
    IN: none 
    OUT: istream &In, Myfloat & x 
Returns: reference to istream 
Preconditions: none 
*******************************************************************/ 

istream & operator>> (istream &In, MyFloat & X) 
{ 
    int Counter=0; 
    char Character; 

    cin.ignore(); // clear newline from input buffer, my algorithm doesn't 
        // work if newline is in input buffer when entering function 

    X.NumberOfDigits=0; 

    cin.get(Character); 

    while ((isspace(Character) || Character=='0') && (Character != '\n')) 
     cin.get(Character); 

    if (Character != '.') 
     return In; 

    cin.get(Character); 

    while (isdigit(Character) && Counter<=X.MaxNumberOfDigits-1) 
    { 
     X.Number[Counter]= Character-'0'; 
     cin.get(Character); 
     ++Counter; 
    } 

    cin.putback(Character);//puts back last character stored - newline in this case 

    X.NumberOfDigits= Counter; 

    for (; Counter<=X.MaxNumberOfDigits-1; ++Counter) 
    { 
     X.Number[Counter]=0; 
    } 

    cin.ignore(100, '\n'); // flush any extra numbers in input - mostly for when 
          // user types in a number longer than array can hold 

    return In; 
} 

Antwort

2

Ein typischer Zuweisungsoperator für Klasse C kehrt C& - eine Referenz auf das Objekt auf der linken Seite der Zuweisung.

Ihrerseits gibt stattdessen eine Kopie dieses Objekts nach Wert zurück. Es ist diese temporäre Kopie, die dann sofort zerstört wird.

+0

@ πάνταῥεῖ Nein, tun sie nicht. Warum fragst du? Ich bin mir nicht sicher, ob ich mit dieser Frage genau dem folge, was Sie fahren. –

+0

@ πάνταῥεῖ Muss ich? Färbe mich dicht, aber ich sehe nicht, wo ich sowas sage. Die Wörter "Konstruktor" oder "Retunn" erscheinen nie einmal in meiner Antwort. –

+0

Diese Art von sinnvoll, indem Sie den Rückgabetyp sowohl die Prototyp- und Funktionsdefinition von MyFloat zu MyFloat & ändern, werden sowohl der Kopierkonstruktorfunktionsaufruf als auch der Destruktorfunktionsaufruf aus dem Prozess eliminiert. Obwohl, um ehrlich zu sein, ich bin immer noch ein wenig unklar, was zerstört wird (im ursprünglichen Code, der es wertmäßig zurückgibt). Eine Kopie des Objekts im Zuweisungsoperator? Oder die Kopie, die zurückgegeben wird? –