简体   繁体   中英

C++ template class, how to declare a copy constructor for a specific situation?

Hi (English is not my first language, please understand me even if I make mistakes! thank you!!)

I'm writing a template class that can contain a pointer.

template <typename T>
class SmartPtr {
private:
      T value;
public:
      SmartPtr() {};
      ~SmartPtr() {};

     SmartPtr(T* a)
     {
        this->value = *a;
     }
     SmartPtr(SmartPtr* a)
     {
          this->value = a->get_Value();
     }
     SmartPtr(SmartPtr const* a)
     {
          this->value = a->get_Value();
     }

     T get_Value()const{
          return this->value;
     }
};

This is template class called SmartPtr, and

class Test
{
public:
      Test() { std::cout << "Test::Test()" << std::endl; }

      Test(Test const&) { std::cout << "Test::Test(Test const&)" << std::endl; }

      ~Test() { std::cout << "Test::~Test()" << std::endl; }

      Test& operator=(Test const&)
      {
           std::cout << "Test& Test::operator=(Test const&)" << std::endl;
           return *this;
      }

      void print() const { std::cout << "Test::print() const" << std::endl; }
      void print() { std::cout << "Test::print()" << std::endl; }
};

this is my Test class.

When I declare

SmartPtr<Test> ptr_t1 = SmartPtr<Test>(new Test); in my main.cpp,

the result after compiling is

Test::Test()
Test::Test()
Test& Test::operator=(Test const&)
Test::~Test()

but the result that I want to get is

Test::Test()
Test::~Test()

Is there a specific template class copy contructor that I need to write in this situation?

Thank you so much for your patience!

The reason is because of inside SmartPtr there is the value member variable:

template <typename T>
class SmartPtr {
private:
      T value; // here T is of class Test
... other stuff ...
}

When declaring

SmartPtr<Test> ptr_t1 = SmartPtr<Test>(new Test);

ptr_t1 is construct, thus it's value is constructed. So that's the first Test() constructor call. The second constructor is the new Test (obviously). Then, the SmartPtr is constructed, and inside, the this->value = *a; calls the Test() assignment operator.

Finally the SmartPtr<Test>(new Test) object is destructed, calling the destructor on the internal value object.

Note also because there was a new Test called, but no delete , there is a memory leak as well.

In order for only the constructor and destructor to be called, simply call the constructor directly:

SmartPtr ptr_t1(new Test);

Also, your SmartPtr class should store a pointer instead of the value. The value can reside in memory allocated by the call to new. Instead of:

private: T value;

write:

private: T* value;

This will ensure that the value isn't copied by the constructor, but is instead just pointed to. The value will still reside at the memory allocated by new.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM