For a little background, I have been studying c++ for 3 months so I'm basically a newbie and I'm trying to understand classes that contain raw pointers as data members and how to use copy-contractors and move semantics with them.

So I have this simple class that contains a simple constructor/destructor and an unimplemented copy-constructor.

All I'm doing is creating an object using said class and then calling a member function with it.

So my question is:

Can I somehow always guaranty that when I call a member function I will make a copy of the object calling it and not pass it by reference?

You can easily pass something by reference if you add the "&" operator but what about passing something by value? I have read that pass by value is the default way the compiler does it but for some reason when I execute my code the copy constructor is not called.

using namespace std;

    class dog {
    public:
        string* name;
        int* age;

        dog(string NameVal = { "Null" }, int AgeVal = { 10 }) { 
            name = new string{ NameVal };
            age = new int{ AgeVal };
            cout << "constructor for " << *name << endl;
        }
        ~dog() {
            cout << "destructor for " << *name << " " << age << endl;
        }
        dog(const dog &source) {
            cout << "copy constructor for " << *name << endl;
        }
        void talk(string text) {
            cout << text << *name << endl;
        }
    };

    int main() {
        dog test;

        test.talk("Test_Text ");
        return 0;
    }

So I expected the copy constructor to get called for the test object but it looks like it gets passed by reference using the "this" pointer.

How could I change that and actually make a copy of the object when calling the function?

Thanks for any help.

2 Answers

1
VTT On Best Solutions

Well, if you want to copy the object and then call a function on the new object then you will need to do it explicitly:

dog test{};
dog{test}.talk("copy talk");

Note that you will also need to actually implement the copy constructor for this to work, otherwise class fields will be left uninitialized:

dog(const dog &source)
: name{new string{*(source.name)}}
, age{new int{*(source.age)}}
{
       cout << "copy constructor for " << *name << endl;
}
1
bruno On

Is there a way to always pass by value (Make a copy) rather than passing by reference when working with class member functions?

use a static operation receiving the instance by value

class dog {
       ...
       static void talk(dog inst, string text) {
            cout << text << *(inst.name) << endl;
        }
       ...
};

int main() {
    dog test;

    dog::talk(test, "Test_Text ");
    // or even
    test.talk(test, "Test_Text ");
}