Home > Software design >  copy constructor do not work in cpp template
copy constructor do not work in cpp template

Time:10-23

I'm writing a test program about c type erasure, the code is put on the end.

when I run program , the test case 2 output as follow:

A default cstr...0x7ffe0fe5158f

obj_:0x7ffe0fe5158f objaaa 0x7ffe0fe5158f

Print A 0x7ffe0fe5158f

my machine: Linux x86-64, gcc 4.8

In my opinion, "Object obj2(a2);" makes a class Model by lvalue reference, so it should call A's copy constructor, but actually it did not work, it makes me confused.

someone can give a explanation, thank you in advance.

the program is list as follow:

#include <memory>
#include <iostream>
class Object {
public:
    template <typename T>
    Object(T&& obj) : object_(std::make_shared<Model<T>>(std::forward<T>(obj))) {
        
    }
    void PrintName() {
        object_->PrintName();
    }
private:
    class Concept {
    public:
        virtual void PrintName() = 0;
    };
    template <typename T>
    class Model : public Concept {
    public:
        Model(T&& obj) : obj_(std::forward<T>(obj)) {
            std::cout << "obj_:" << std::addressof(obj_) <<" objaaa "   << std::addressof(obj) << std::endl;
        }

        void PrintName() {
            obj_.PrintName();
        }

    private:
        T obj_;
    };
private:
    std::shared_ptr<Concept> object_;
};

class A {
public:
    A(A& a) {
        std::cout<< "A copy cstr...a" << this << std::endl;
    }
    A(A&& a) {
        std::cout << "A move cstr...." <<this<< std::endl;
    }
    A() {
        std::cout << "A default cstr..." <<this<< std::endl;
    }
    void PrintName() {
        std::cout << "Print A " << this << std::endl;
    }
};


int main(void)
{
    // test case 1
    Object obj{A()};
    obj.PrintName();

    // test case 2
    A a2;
    Object obj2(a2);
    obj2.PrintName();
    return 0;
}

CodePudding user response:

In Object obj2(a2);, no copy is made. T in the constructor of Object is deduced to be A&, so it instantiates Model<A&>, which stores a reference to the original a2 object as its obj_ member.

Observe that in your debug output, a2's constructor, Model's constructor and PrintName all print the same address. You can further confirm that this address is in fact &a2.

  • Related