“main.cpp”
int main()
{
Mystring larry3 = "larry3"; //will call no-arg ctor not move ctor.
Mystring larry4 = larry3; // deep copy ctor is being called correctly
std::cout <<"before" << endl;
larry4 = "larry4"; // move assignment operator is being called correctly
larry4 = Mystring{"larry4Again"}; // move assignment should be called -- but things
// seems to be messed after this line
larry4.display(); // this is also not working
std::cout <<"after" << endl; // this is also not working
return 0;
}
“Mystring.cpp”
//
// Created by kumarg on 17-11-2024.
//
#include "Mystring.h"
#include <iostream>
#include <cstring>
//no-arg ctror
Mystring::Mystring()
:str{nullptr} {
str = new char[1];
*str = '\0'; //
cout << "no-arg ctor" << endl;
}
//arg ctor
Mystring::Mystring(const char *s)
:str{nullptr}{
if(s == nullptr) { //if s points to nullptr then do same thing as no-arg ctor
this->str = new char[1]; // this->str or str is same used in 3rd line from here
*str = '\0';
} else {
str = new char[std::strlen(s) + 1];
std::strcpy(this->str, s);
}
std::cout << "arg-ctor" <<endl;
}
//dtor
Mystring::~Mystring() {
std::cout << "dtor called: " << str << endl;
delete []str;
}
void Mystring::display() const {
std::cout << this->str << endl;
}
//copy ctor - deep
Mystring::Mystring(const Mystring &source)
:str{nullptr} {
std::cout << "deep copy ctor" << endl;
str = new char[std::strlen(source.str) +1];
std::strcpy(this->str, source.str);
}
//move ctor
Mystring::Mystring(Mystring &&source)
:str{source.str} {
cout << "move ctor" << endl;
source.str = nullptr;
}
//copy assignment operator implementation
Mystring &Mystring::operator=(const Mystring &rhs) {
std::cout << "copy assignment operator" << endl;
//check if both are same already
if(this == &rhs)
return *this;
delete []str;
str = new char[std::strlen(rhs.str) + 1];
std::strcpy(this->str, rhs.str);
return *this;
}
//move assignment operator
Mystring &Mystring::operator=(Mystring &&rhs) {
std::cout << "move assignment operator" << endl;
if(this == &rhs)
return *this;
delete []str;
str = rhs.str;
rhs.str = nullptr;
return *this;
}
“Mystring.h”
//
// Created by kumarg on 16-11-2024.
//
#ifndef MYSTRING_H
#define MYSTRING_H
#include <iostream>
using namespace std;
class Mystring {
private:
char *str;
public:
Mystring(); // default ctor
Mystring(const char *source); //parameter ctor
~Mystring();
Mystring(const Mystring &source); //copy ctor
Mystring(Mystring &&source) noexcept; //move ctor
void display() const;
Mystring operator-(); // unary - operator overloading
bool operator==(Mystring &rhs); // assignment operator overloading
bool operator!=(Mystring &rhs); // !- operator overloading
bool operator<(Mystring &lhs);
bool operator>(Mystring &lhs);
Mystring operator+(Mystring &lhs);
//assignment (=) operator overloading, remember this called when we do s2 = s1(both are initilaized already)
// = operator can be overloaded in 2 ways, copy and move, if l-value thenp copy will be called, if r-value move will be called
Mystring &operator=(const Mystring &rhs);
// = op overloading by move
Mystring &operator=(Mystring &&rhs);
//Mystring &operator+=(Mystring &lhs);
};
#endif //MYSTRING_H
我的代码按照预期执行,直到 main.c 中的第
larry4 = "larry4"
行。
但在这一行之后,即 larry4 = Mystring{"larry4Again"};
我期待着 arg-ctor 调用,然后移动赋值调用。所以我期待着来自 arg-ctor 的 cout,然后是来自移动运算符赋值调用的 cout。最后我期待着来自 main 的 cout。这一切都没有发生。
问题是,在您的
Mystring
析构函数 (Mystring::~Mystring
) 中,尝试在这一行中打印它时,您不会检查 str
是否为空:
std::cout << "dtor called: " << str << endl;
您可以通过将打印语句更改为来修复它:
if (str) {
std::cout << "dtor called: " << str << endl;
}
else {
std::cout << "dtor called (null)" << endl;
}