最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

c++ - Why is the move constructor is not being called? - Stack Overflow

matteradmin3PV0评论

Below is my C++ code. I was expecting my move ctor to be called here in my main:

Mystring larry2 = "some larry";

main.cpp:

int main()
{
    //Mystring no_name;
    Mystring larry ("LARRY");
    Mystring larry1 {larry}; // deep copy ctor is called
    Mystring larry2 = "some larry"; // move ctor should be called but still calling parameterized ctor
}

Mystring.cpp:

Mystring::Mystring()
    :str{nullptr} {
    cout <<"default ctor called" <<endl;
    str = new char[1];
    *str = '\0';
}

Mystring::Mystring(const char *s)
    :str{nullptr} {
    cout << "param ctor called" << endl;
    if(s == nullptr) {
        // then do same as default ctor;
        str = new char[1];
        *str = '\0';
    }else {
        str = new char[std::strlen(s) + 1];
        std::strcpy(str, s);
    }
}

Mystring::~Mystring() {
    cout << "dtor called: " << this->str << endl;
    delete []str;
}

//deep copy ctor implementation
Mystring::Mystring(const Mystring &source)
    :str{nullptr} {
    cout << "deep copy ctor called" <<endl;
    str = new char[std::strlen(source.str) + 1];
    std::strcpy(str, source.str);
}

//move ctor implementation
Mystring::Mystring(Mystring &&source) noexcept
    :str(source.str) {
    cout << "move ctor called" << endl;
    source.str = nullptr;
}
 
void Mystring::display() const {
    cout << this->str << endl;
}

Mystring.h:

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

I tried multiple sources.

Below is my C++ code. I was expecting my move ctor to be called here in my main:

Mystring larry2 = "some larry";

main.cpp:

int main()
{
    //Mystring no_name;
    Mystring larry ("LARRY");
    Mystring larry1 {larry}; // deep copy ctor is called
    Mystring larry2 = "some larry"; // move ctor should be called but still calling parameterized ctor
}

Mystring.cpp:

Mystring::Mystring()
    :str{nullptr} {
    cout <<"default ctor called" <<endl;
    str = new char[1];
    *str = '\0';
}

Mystring::Mystring(const char *s)
    :str{nullptr} {
    cout << "param ctor called" << endl;
    if(s == nullptr) {
        // then do same as default ctor;
        str = new char[1];
        *str = '\0';
    }else {
        str = new char[std::strlen(s) + 1];
        std::strcpy(str, s);
    }
}

Mystring::~Mystring() {
    cout << "dtor called: " << this->str << endl;
    delete []str;
}

//deep copy ctor implementation
Mystring::Mystring(const Mystring &source)
    :str{nullptr} {
    cout << "deep copy ctor called" <<endl;
    str = new char[std::strlen(source.str) + 1];
    std::strcpy(str, source.str);
}

//move ctor implementation
Mystring::Mystring(Mystring &&source) noexcept
    :str(source.str) {
    cout << "move ctor called" << endl;
    source.str = nullptr;
}
 
void Mystring::display() const {
    cout << this->str << endl;
}

Mystring.h:

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

I tried multiple sources.

Share Improve this question edited Nov 18, 2024 at 16:22 genpfault 52.2k12 gold badges91 silver badges151 bronze badges asked Nov 17, 2024 at 17:27 gaurav sgaurav s 595 bronze badges 1
  • 1 "move ctor should be called" -- copy/move constructors can be elided even when they are logically present – Gene Commented Nov 17, 2024 at 19:15
Add a comment  | 

1 Answer 1

Reset to default 5

I assume you expected a move ctor in this line:

Mystring larry2 = "some larry"; 

because you thought a temporary object is first constructer from "some larry", and then it is moved into larry2.

But in fact this line is not performing an assignment, but rather an intialization of larry2.

It is equivalent to:

Mystring larry2{"some larry"}; // or: larry2("some larry");

And therefore invokes a single call of the constructor that accepts a const char*.

A side note:
It's better to avoid using namespace std; - see here.

Post a comment

comment list (0)

  1. No comments so far