dimanche 5 novembre 2023

Different behaviour for normal and copy constructor [duplicate]

I have below code, when I remove the copy constructor in A, code compiles because I think default copy constructor is generated, which is public, so it gets called.

What I am trying to achieve is Prototype factory where I want to first create an object x and then replicate that object. I want to make sure that only Prototype factory is used to replicate the object and I don't want main() to call copy constructor in A directly. Anyone who wants to replicate has to use the factory dfunc(). How do I acheive this ?

Point to note here is that A(int, int) constructor gets called even if it is private, but strangely for copy constructor compiler complains that it is private.

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

using namespace std;

class A {
    friend ostream& operator<<(ostream& os, const A& aa);
    int a, b;

    A(int a, int b) : a(a), b(b) { cout << __PRETTY_FUNCTION__ << endl; }

    A(const A& aa) : a(aa.a), b(aa.b) { cout << __PRETTY_FUNCTION__ << endl; }

public:
    class C {
    public:
        static A cfunc(int x, int y) {
            cout << __PRETTY_FUNCTION__ << endl;
            return A{x, y};
        }
    };

    class D {
    public:
        static unique_ptr<A> dfunc(const A& aa) {
            cout << __PRETTY_FUNCTION__ << endl;
            return make_unique<A>(aa);
        }
    };
};

ostream& operator<<(ostream& os, const A& aa) {
    os << "(" << aa.a << "," << aa.b << ")";
    return os;
}

int main() {
    auto x = A::C::cfunc(10, 11);
    auto y = A::D::dfunc(x);

    cout << x << endl;
    cout << *y << endl;

    return 0;
}
test05.cpp:55:30: error: ‘A::A(const A&)’ is private within this context
   55 |   auto x = A::C::cfunc(10, 11);
      |                              ^
test05.cpp:19:3: note: declared private here
   19 |   A(const A& aa): a(aa.a), b(aa.b)
      |   ^
In file included from /usr/include/c++/9/memory:80,
                 from test05.cpp:3:
/usr/include/c++/9/bits/unique_ptr.h: In instantiation of ‘typename std::_MakeUniq<_Tp>::__single_object std::make_unique(_Args&& ...) [with _Tp = A; _Args = {const A&}; typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<A>]’:
test05.cpp:41:31:   required from here
/usr/include/c++/9/bits/unique_ptr.h:857:30: error: ‘A::A(const A&)’ is private within this context
  857 |     { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
      |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test05.cpp:19:3: note: declared private here
   19 |   A(const A& aa): a(aa.a), b(aa.b)
      |   ^

Aucun commentaire:

Enregistrer un commentaire