是否可以使用非常量指针调用非常量函数,以及当两个 unique_ptrs 指向同一个对象时程序将如何运行?
Can a non-const function be called using a non-const pointer and how the program will behave when two unique_ptrs point to the same objec?
第一题:
现在我有两个 unique_ptr
(ptrToBase
和 ptrToDerived
)指向同一个对象(由 make_unique
制作)。那么程序行为是未定义的还是如何销毁两个指针?
第二个:
指针as_const(ptrToDerived)
是constatn。尽管 function2
是一个非常量函数
,但它是如何被调用的
#include <iostream>
#include<vector>
using namespace std;
class Base{
public:
virtual void function()const{
cout<<"\n"<<__FUNCSIG__;
}
virtual~Base(){cout<<"\n"<<__FUNCSIG__;}
};
class Derived : public Base
{
public:
int var{9};
virtual void function()const override{
cout<<"\n"<<__FUNCSIG__<<"\nvar: "<<var;
}
void function1()const{
cout<<"\n"<<__FUNCSIG__;
}
void function2(){
cout<<"\n"<<__FUNCSIG__;
}
virtual~Derived(){cout<<"\n"<<__FUNCSIG__;}
};
int main()
{
//ptr of type Base* pointing to an object of type of Derived
unique_ptr<Base> ptrToBase {make_unique<Derived>()};
unique_ptr<Derived> ptrToDerived {dynamic_cast<Derived*>(ptrToBase.get())};
if (ptrToDerived) ptrToDerived->function1();
as_const(ptrToDerived)->function2();
return 0;
}
So is the program behavior undefined or how will it work on destroying the two pointers?
是的,因为双重破坏,它有UB。不要这样做。
the pointer as_const(ptrToDerived) is constatn. how function2 can be called although it's a non-constant function
std::as_const
将使它成为 const std::unique_ptr<Derived>
而不是 std::unique_ptr<const Derived>
这就是调用 function2()
的原因。
另一方面,这将不起作用:
unique_ptr<const Derived> ptrToDerived{dynamic_cast<Derived*>(ptrToBase.get())};
ptrToDerived->function2();
可能的编译器输出:
source>:41:29: error: passing 'const Derived' as 'this' argument discards qualifiers [-fpermissive]
41 | ptrToDerived->function2();
您可以通过以下几种方式解决双删问题。
如果您知道您希望对象的生命周期由一个 unique_ptr 控制,您可以创建一个简单的 observer_ptr,它将保存一个指针但不会尝试销毁该对象:
// a deleter that will not delete
struct no_delete
{
template<class P>
void operator()(P*) const noexcept
{
// nothing;
}
};
template<class T>
using observer_ptr = std::unique_ptr<T, no_delete>;
如果您希望对象的生命周期在最后一个指针超出范围时结束,并且您不知道哪个先超出范围,那么您需要 std::shared_ptr
第一题:
现在我有两个 unique_ptr
(ptrToBase
和 ptrToDerived
)指向同一个对象(由 make_unique
制作)。那么程序行为是未定义的还是如何销毁两个指针?
第二个:
指针as_const(ptrToDerived)
是constatn。尽管 function2
是一个非常量函数
#include <iostream>
#include<vector>
using namespace std;
class Base{
public:
virtual void function()const{
cout<<"\n"<<__FUNCSIG__;
}
virtual~Base(){cout<<"\n"<<__FUNCSIG__;}
};
class Derived : public Base
{
public:
int var{9};
virtual void function()const override{
cout<<"\n"<<__FUNCSIG__<<"\nvar: "<<var;
}
void function1()const{
cout<<"\n"<<__FUNCSIG__;
}
void function2(){
cout<<"\n"<<__FUNCSIG__;
}
virtual~Derived(){cout<<"\n"<<__FUNCSIG__;}
};
int main()
{
//ptr of type Base* pointing to an object of type of Derived
unique_ptr<Base> ptrToBase {make_unique<Derived>()};
unique_ptr<Derived> ptrToDerived {dynamic_cast<Derived*>(ptrToBase.get())};
if (ptrToDerived) ptrToDerived->function1();
as_const(ptrToDerived)->function2();
return 0;
}
So is the program behavior undefined or how will it work on destroying the two pointers?
是的,因为双重破坏,它有UB。不要这样做。
the pointer as_const(ptrToDerived) is constatn. how function2 can be called although it's a non-constant function
std::as_const
将使它成为 const std::unique_ptr<Derived>
而不是 std::unique_ptr<const Derived>
这就是调用 function2()
的原因。
另一方面,这将不起作用:
unique_ptr<const Derived> ptrToDerived{dynamic_cast<Derived*>(ptrToBase.get())};
ptrToDerived->function2();
可能的编译器输出:
source>:41:29: error: passing 'const Derived' as 'this' argument discards qualifiers [-fpermissive]
41 | ptrToDerived->function2();
您可以通过以下几种方式解决双删问题。
如果您知道您希望对象的生命周期由一个 unique_ptr 控制,您可以创建一个简单的 observer_ptr,它将保存一个指针但不会尝试销毁该对象:
// a deleter that will not delete
struct no_delete
{
template<class P>
void operator()(P*) const noexcept
{
// nothing;
}
};
template<class T>
using observer_ptr = std::unique_ptr<T, no_delete>;
如果您希望对象的生命周期在最后一个指针超出范围时结束,并且您不知道哪个先超出范围,那么您需要 std::shared_ptr