我目前正在尝试创建一个自定义的 SmartPointer 类,与内置的 C++ 智能指针不同,它将执行我想要的操作。目标是能够将任何类/结构转换为智能指针,并且使所述类/结构可继承到该类的智能指针版本也可继承。
例如,如果我有类
Parent
,而类 ChildA
和类 ChildB
继承自,则还会有类型 Parentsp
、ChildAsp
和 ChildBsp
。我希望能够编写以 Parentsp
作为参数的函数,但能够向其传递 ChildAsp
或 ChildBsp
类型。如 print(Parentsp p)
所示,并用 ChildAsp
和 ChildBsp
类型来调用它。我当前的 SmartPointer 和 RefCounter 设置如下。
class RefCounter {
public:
void AddRef() {count++;}
int Release() {return --count;}
private:
int count;
};
template<typename T>
class SmartPointer {
public:
SmartPointer() : mPtr(nullptr), mRef(nullptr) {
mRef = new RefCounter();
mRef->AddRef();
}
SmartPointer(T* mPtr) : mPtr(mPtr), mRef(nullptr) {
mRef = new RefCounter();
mRef->AddRef();
}
SmartPointer(const SmartPointer<T>& other) : mPtr(other.mPtr), mRef(other.mRef){
mRef->AddRef();
}
~SmartPointer(){
if(mRef->Release() == 0) {
delete mPtr;
delete mRef;
}
}
T& ptr(){
return *mPtr;
}
T& operator*(){
return *mPtr;
}
T* operator->(){
return mPtr;
}
SmartPointer<T>& operator=(const SmartPointer<T>& other) {
if (this != &other) {
if(mRef->Release() == 0) {
delete mPtr;
delete mRef;
}
mPtr = other.mPtr;
mRef = other.mRef;
mRef->AddRef();
}
return *this;
}
private:
T* mPtr;
RefCounter* mRef;
};
目前,我将上面的内容与以下宏一起使用:
MAKE_SP(cls) typedef SmartPointer<cls> cls##sp
这为我提供了给定类的 SmartPointer 类型,但继承性不会转移。我尝试过从
SmartPointer<type>
继承,但这也不起作用。我知道可能需要从 SmartPointer 继承,但我不知道如何去做并保持 typedef type+sp 类型的能力。我是否需要在 SmartPointer 和其他类之间有一个中间类来继承?我需要放弃模板智能指针吗?
将智能指针从子类传递到要求指向父类的智能指针的参数已经是可能的。
#include <memory>
class Parent {};
class Child : public Parent {};
void foo(const std::shared_ptr<Parent> &p) {}
int main(int argc, char* argv[])
{
std::shared_ptr<Child> c = std::make_shared<Child>();
foo(c);
}
https://godbolt.org/z/a8efo8YoW
如果您想为了好玩而重新实现它,那没问题,但您应该知道这已经是可能的
我不太明白
std::shared_ptr
对你不起作用;你能详细说明一下吗?
希望能够编写以 Parentsp 作为参数的函数,但能够向其传递 ChildAsp 或 ChildBsp 类型。
所以,这个?
#include <memory>
class Parent
{
public:
typedef std::shared_ptr<Parent> Ptr;
};
class ChildA: public Parent
{
public:
typedef std::shared_ptr<ChildA> Ptr;
};
class ChildB: public Parent
{
public:
typedef std::shared_ptr<ChildB> Ptr;
};
void function(Parent::Ptr)
{
}
int main()
{
ChildA::Ptr childA=std::make_shared<ChildA>();
function(childA);
return 0;
}