1

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.

1
  • 1
    "move ctor should be called" -- copy/move constructors can be elided even when they are logically present Commented Nov 17, 2024 at 19:15

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

5 Comments

thanks for suggestion on "std", I will keep that in mind. coming back to original question, can i please ask what call i can make from main to invoke my move constructor call. I really want to understand where is this being used.
@gauravs Mystring larry1 {std::move(larry)}; would be a move construction.
@gauravs • I got a similar move construction like BoP, Mystring larry3 = move(Mystring{"move larry"});. There is some almost irrelevant differences between the = and the {...}, but it's mostly syntactic sugar — except when the irrelevant differences become relevant. C++: the bugs practically write themselves.
@gauravs in addition to the above, another example for using a move constructor is if you have a function like f(Mystring s) and you call it with f(std::move(larry)); then s would be move constructed from larry.
@gauravs see more info and examples for move constructor here: Move constructors.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.