There is no difference between lines 82 and 92 in the code below with both MSVC2022 and GCC11:
#include <utility>
#include <stdexcept>
#include <iostream>
struct Object
{
virtual const char* name() = 0;
virtual ~Object() = default;
};
struct A : public Object
{
const char* name() override
{
return "A";
}
};
struct B : public Object
{
B()
{
throw std::runtime_error("");
}
const char* name() override
{
return "B";
}
};
template <class T>
class MyPtr
{
public:
MyPtr(T* p) : m_p(p)
{
std::cout << "Created MyPtr<" << m_p->name() << ">" << std::endl;
}
MyPtr(const MyPtr& other) = delete;
MyPtr(MyPtr&& other) noexcept : m_p(other.m_p)
{
std::cout << "Move constructor of MyPtr<" << m_p->name() << ">" << std::endl;
other.m_p = nullptr;
}
~MyPtr()
{
std::cout << "Destroying MyPtr<" << m_p->name() << ">" << std::endl;
delete m_p;
}
private:
T* m_p;
};
class Foo
{
public:
Foo(MyPtr<B> b, MyPtr<A> a) : m_a(std::move(a)), m_b(std::move(b)) {}
private:
MyPtr<A> m_a;
MyPtr<B> m_b;
};
int main()
{
try
{
std::cout << "Naked pointer:" << std::endl;
Foo foo(new B(), new A());
}
catch (const std::exception&)
{
}
try
{
std::cout << "Smart pointer:" << std::endl;
Foo foo(MyPtr(new B()), MyPtr(new A()));
}
catch (const std::exception&)
{
}
return 0;
}
The output is:
Naked pointer:
Created MyPtr<A>
Destroying MyPtr<A>
Smart pointer:
Created MyPtr<A>
Destroying MyPtr<A>
Compiling with GCC from the command line:
g++ -std=c++20 -pthread -O3 a.cpp -o a20