-2

I am a little confused with the copy constructor and references in c++.

Kat kat("hello kitty");
Kat newKat = kat;

Will Kat use its copy constructor or will newKat just become a reference to Kat.

Edit: sorry for the confusion, I mean for custom types.

Vexea
  • 167
  • 1
  • 1
  • 8
  • 4
    Primitive types aren't objects, there are no constructors involved. In this case, a copy of the value of `x` is assigned to `y`. Someone with deeper knowledge might chime in. – sweenish Dec 08 '21 at 15:30
  • 1
    `y` will be a copy of `x`, not reference. – songyuanyao Dec 08 '21 at 15:30
  • 3
    @sweenish C++ has a strict definition of "[object](https://en.cppreference.com/w/cpp/language/object)" and `int x` and `int y` are both objects. You may be thinking of "class type"? – François Andrieux Dec 08 '21 at 15:32
  • @FrançoisAndrieux That's good information. An object has been, until now, an instance of a class type for me. – sweenish Dec 08 '21 at 15:34
  • https://stackoverflow.com/questions/1051379/is-there-a-difference-between-copy-initialization-and-direct-initialization – Cory Kramer Dec 08 '21 at 15:34
  • 2
    `Kat& refKat = kat;` would be a reference to `kat`. – Eljay Dec 08 '21 at 15:34
  • There are no references in your code at all, as those are clearly marked by `&` following types. Unlike other languages, C++ is very specific when it comes to distinguishing between objects, pointers to them and references. – SergeyA Dec 08 '21 at 15:34
  • I am sorry, I am from c# and there object assignments are references by default. – Vexea Dec 08 '21 at 15:35
  • 2
    C++ has value semantics. So `T x = y;` always creates a new instance of `T`. Whether that means their values are independent copies or somehow connected depends on the type `T`. Usually values are copied, but for example `std::shared_ptr x = y;` may imply a shared state. – François Andrieux Dec 08 '21 at 15:35
  • 2
    @Vexea Basically everything in C++ behaves like a `struct` (a value type) in C#. You can use `&` to get a reference type, but C++ references do not extend object lifetime (except in a few specific cases). A `std::shared_ptr` is the closest standard thing C++ has to a C# reference type. – François Andrieux Dec 08 '21 at 15:36
  • Alright, someone also answered the question but I got to wait 7 minutes before accepting. – Vexea Dec 08 '21 at 15:37
  • 1
    @Vexea *"but I got to wait 7 minutes before accepting."* -- that's to give other people a chance to answer. The first correct answer is not always the best correct answer. Don't feel obligated to accept an answer as soon as you are allowed to. It wouldn't be wrong to wait longer (perhaps a day?) before accepting to see if other people want to contribute. – JaMiT Dec 08 '21 at 15:41

3 Answers3

2
Kat kat("hello kitty");
Kat newKat = kat;

Will use the copy constructor

Kat kat("hello kitty");
Kat& newKat = kat;

Will create a reference

0

Since when creating the Kat object you don't use the new keyword and your variable is not a reference type (See more) (or pointer) the object is being created on the Stack. Assigning objects from the stack will result in them getting copied, so it will use the copy constructor.

66Gramms
  • 769
  • 7
  • 23
  • 2
    You may want to edit / remove your answer after latest edits. – SergeyA Dec 08 '21 at 15:33
  • 1
    Been there, done that – 66Gramms Dec 08 '21 at 15:43
  • 1
    Whether the object is "on the stack" or not doesn't really matter. If you used `new` and dereferenced the pointer to perform an assignment, you would get the same result. What matters is the type of object being used and what they mean by "reference". If you used pointers and assigned pointers, the pointers themselves would still be copies, even if they point to a shared value. The topic is tricky. – François Andrieux Dec 08 '21 at 15:44
  • You are right, and this expands my answer nicely. I wanted to answer the question and just that so it wouldn't be too overwhelming. – 66Gramms Dec 08 '21 at 15:49
0

I think this can be a better answer to your question since you need to understand all of the special member functions and not just the copy constructor.

Now take a look at this:

#include <iostream>
#include <utility>
#include <string>


class Kat
{
public:
    Kat( )
    :msg( "Default Msg" )
    {
        std::clog << "default ctor" << '\n';
    }

    Kat( const std::string& message )
    : msg( message )
    {
        std::clog << "parameterized ctor" << '\n';
    }

    Kat( const Kat& rhs )                // copy ctor
    : msg( rhs.msg )
    {
        std::clog << "copy ctor" << '\n';
    }

    Kat& operator=( const Kat& rhs )     // copy assignment operator
    {
        if ( this != &rhs )
        {
            msg = rhs.msg;
        }

        std::clog << "copy assignment operator" << '\n';

        return *this;
    }

    Kat( Kat&& rhs ) noexcept            // move ctor
    : msg( rhs.msg )
    {
        rhs.msg = "";

        std::clog << "move ctor" << '\n';
    }

    Kat& operator=( Kat&& rhs ) noexcept // move assignment operator
    {
        if ( this != &rhs )
        {
            msg = rhs.msg;

            rhs.msg = "";
        }

        std::clog << "move assignment operator" << '\n';

        return *this;
    }

private:
    std::string msg;
};

int main( )
{
    Kat kat1; // default ctor
    Kat kat2( "hello kitty" ); // parameterized ctor

    Kat kat3 = kat2; // copy ctor
    Kat kat4( kat2 ); // also copy ctor

    kat1 = kat2; // copy assignment operator

    Kat kat5 = std::move( kat2 ); // move ctor
    Kat kat6( std::move( kat3 ) ); // also move ctor

    kat6 = std::move( kat1 ); // move assignment operator

    return 0;
}

And the output:

default ctor
parameterized ctor
copy ctor
copy ctor
copy assignment operator
move ctor
move ctor
move assignment operator
digito_evo
  • 3,216
  • 2
  • 14
  • 42