在托管C ++ / CLI中覆盖继承的泛型方法

时间:2015-11-30 14:00:12

标签: .net c++-cli

我在C#中编写代码并且工作正常:

public interface IBase<T>
{
}

public abstract class BaseImpl<T> : IBase<T> 
{
    public abstract T2 CreateInstance<T2>();
}

public class InstanceX : BaseImpl<string>
{
    public override T2 CreateInstance<T2>() 
    {
        return default(T2); 
    }
}

public class TestInstanceX
{
    void TestIt() 
    {
        InstanceX mProvX = new InstanceX();
        string str1 = mProvX.CreateInstance<String>();
    }
}

我试图将其移至托管c ++:

generic <typename T>
public ref class BaseImpl abstract: IBase<T> 
{
public:

    generic <typename T2>
    virtual T2 CreateInstance() abstract;

};

public ref class InstanceX : BaseImpl<String^>
{
public:
    generic <typename T2>
    virtual T2 CreateInstance() override
    {
        return (T2)(Object^) nullptr; 
    }
};

public ref class TestInstanceX
{
    void TestIt() 
    {
        InstanceX^ mProvX = gcnew InstanceX();
        String^ str1 = mProvX->CreateInstance<String^>();
    }
};

在托管C ++中,我收到编译器错误:

  

Test.h:错误C229:'InstanceX':无法实例化抽象类            由于以下成员:            'T2 BaseImpl :: CreateInstance(void)':是抽象的            同            [                T = System :: String ^            ]

     

Test.h:查看'BaseImpl :: CreateInstance'的声明            同            [                T = System :: String ^            ]

如何在托管C ++中的InstanceX类中重写(实现)“CreateInstance”函数?

1 个答案:

答案 0 :(得分:0)

这让我觉得这是C ++ / CLI编译器中可能存在的错误。似乎如果基类和子类具有不同的泛型类型(T与不再通用),并且被重写的方法具有不同的泛型类型(T2),那么它不会#39 ; t意识到第二个泛型类型(T2)实际上是相同的。

要解决这个问题,我会创建一个虚拟中间类,它在类型T上仍然是通用的。在那里实现T2泛型方法,然后从中继承InstanceX。

这是我的测试计划。

另外,请注意CreateInstance的实现:与C#default(T)等效的C ++ / CLI是T()。当nullptr是值类型(例如Object^)时,将T2投射到T2然后投放到int会导致NullReferenceException。

generic<typename T>
public interface class IBase
{
};

generic <typename T>
public ref class BaseImpl abstract: IBase<T>
{
public:
    generic <typename T2>
    virtual T2 CreateInstance() abstract;
};

generic <typename T>
public ref class IntermediateJustForOverriding : BaseImpl<T>
{
public:
    generic <typename T2>
    virtual T2 CreateInstance() override
    {
        return T2();
    }
};

public ref class InstanceX : IntermediateJustForOverriding<String^>
{
};

int main(array<System::String ^> ^args)
{
    InstanceX^ mProvX = gcnew InstanceX();
    String^ str1 = mProvX->CreateInstance<String^>();

    Debug::WriteLine(str1);
    Debug::WriteLine(str1 == nullptr);
    Debug::WriteLine(mProvX->CreateInstance<int>());
    return 0;
}

输出:


True
0
相关问题