Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 强制转换多态智能指针对象_C++_Casting_Polymorphism_Smart Pointers_Dynamic Cast - Fatal编程技术网

C++ 强制转换多态智能指针对象

C++ 强制转换多态智能指针对象,c++,casting,polymorphism,smart-pointers,dynamic-cast,C++,Casting,Polymorphism,Smart Pointers,Dynamic Cast,我实现了以下智能指针模板类: #ifndef __ProjectManager__mSharedPtr__ #define __ProjectManager__mSharedPtr__ #include <stdio.h> #include "RefCount.h" template <class T> class mSmartPtr { T *data; RefCount *rc; public: mSmartPtr(T* srcPtr

我实现了以下智能指针模板类:

#ifndef __ProjectManager__mSharedPtr__
#define __ProjectManager__mSharedPtr__

#include <stdio.h>
#include "RefCount.h"

template <class T>
class mSmartPtr {

    T *data;
    RefCount *rc;

public:

    mSmartPtr(T* srcPtr);
    mSmartPtr(const mSmartPtr&);
    ~mSmartPtr();
    T* operator->() const;
    T& operator*() const;
    mSmartPtr<T>& operator=( mSmartPtr&);
    mSmartPtr<T> operator()(mSmartPtr&);
};

template<class T>
mSmartPtr<T> mSmartPtr<T>::operator()(mSmartPtr<T>& src) {
    return dynamic_cast<??>(src);
}

template <class T>
mSmartPtr<T>::mSmartPtr(T *srcPtr):
data(srcPtr) {
    rc = new RefCount();
    rc->add();
}

template<class T>
mSmartPtr<T>::~mSmartPtr() {
    if (rc->remove() == 0) {
        delete data;
        delete rc;
    }
}


template<class T>
mSmartPtr<T>::mSmartPtr(const mSmartPtr<T> &src):
data(src.data), rc(src.rc) {
    rc->add();
}


template <class T>
T* mSmartPtr<T>::operator->() const {
    return data;
}

template<class T>
T& mSmartPtr<T>::operator*() const {
    return &data;
}

template <class T>
mSmartPtr<T>& mSmartPtr<T>::operator=( mSmartPtr<T> &src) {
    if (this != &src) {
        if (rc->remove() == 0) {
            delete data;
            delete rc;
        }
        data = src.data;
        rc = src.rc;
        rc->add();
    }
    return *this;
}



#endif /* defined(__ProjectManager__mSharedPtr__) */
我需要按以下方式存储数据:

int int main(int argc, char const *argv[])
{
    std::vector<mSmartPtr<Base>> v;
    mSmartPtr<Derived1> d1 = foo();

    v.push_back(d1);

    return 0;
}
int-main(int-argc,char-const*argv[]
{
std::向量v;
mSmartPtr d1=foo();
v、 推回(d1);
返回0;
}

我需要以某种方式修复cast操作符,但是如何修复呢?如何在动态转换中获取基类?

在转换方法中,提取底层指针并转换它,然后将其放入新的智能指针中。不要忘记复制
RefCount
,并确保目标类有一个虚拟析构函数(这样无论最后处理哪个智能指针,都会调用正确的析构函数)

我不知道如何在外部定义它,但内联定义起作用了

//In the definition, replacing this line
//mSmartPtr<T> operator()(mSmartPtr&)
template<class Tdest>
operator mSmartPtr<Tdest>() {
    mSmartPtr<Tdest> retVal(static_cast<Tdest*>(data));
    retVal.rc = rc;
    retVal.rc.Add();
    return retVal;
}
//在定义中,替换此行
//mSmartPtr运算符()(mSmartPtr&)
模板
运算符mSmartPtr(){
mSmartPtr retVal(静态_cast(数据));
retVal.rc=rc;
retVal.rc.Add();
返回返回;
}
理论上,如果您使用C++11,您也可以添加一个采用r值的版本,但我认为这需要一些工作才能正确完成,因此我避免了它。

@Guvante

你的代码不起作用,我修改了它如下,但我不知道是否会工作得很好

template<class T>
mSmartPtr<T> mSmartPtr<T>::operator ()(mSmartPtr<T>& src) {
    mSmartPtr<T> retVal(dynamic_cast<T*>(src.data));
    retVal.rc = src.rc;
    retVal.rc.Add();
    return retVal;
}
模板
mSmartPtr mSmartPtr::operator()(mSmartPtr&src){
mSmartPtr retVal(动态_cast(src.data));
retVal.rc=src.rc;
retVal.rc.Add();
返回返回;
}

我认为有更好的替代方案。除非您需要在不同的位置执行此操作,否则可以通过更改创建对象的方式来避免头痛

int main(int argc, char const *argv[])
{
    std::vector<mSmartPtr<Base>> v;
    mSmartPtr<Base> d1 = static_cast<Base*>(foo());

    v.push_back(d1);

    return 0;
}
int main(int argc,char const*argv[])
{
std::向量v;
mSmartPtr d1=静态_转换(foo());
v、 推回(d1);
返回0;
}

只需避免创建与向量类型不同的
mSmartPtr

我之前尝试过的可能重复,它不是指我要解决的cast运算符,也不是与问题直接相关,但正如我所做的:带有两个前导下划线的名称是为编译器和标准库内部使用而保留的:这些行是由Xcode新文件组件生成的..您好,谢谢您的评论。我怎样才能把模板参数添加到类方法中?@itorra:我有这个想法,但没有考虑。我将更新答案以包含该位。@itorra:无法理解它,所以我将其定义为内联(可能是内联的一个好方法)。注意,我还添加了一个单独的答案以避免出现这种情况。您需要另一个模板参数来定义输入或输出类型,具体取决于您如何实现它。不幸的是,我不知道如何将我的重新定义为内联。
int main(int argc, char const *argv[])
{
    std::vector<mSmartPtr<Base>> v;
    mSmartPtr<Base> d1 = static_cast<Base*>(foo());

    v.push_back(d1);

    return 0;
}