如何从基类获得顶级课程

时间:2013-11-25 19:32:06

标签: c++

这是我的示例代码。我想从基地或中产阶级中获得顶级成绩。 我怎样才能做到这一点 ?我不想在任何地方指定顶级名称,我知道我可以写“GetTop< TopClass>();”但是我希望,没有它的方法。

当然,我的代码显示错误:

“错误C2783:'T * BaseClass :: GetTop(void)':无法推断'T'的模板参数”

class BaseClass
{
public:
BaseClass(){}
virtual ~BaseClass() {}

template < class T >
T* GetTop()
{
    return static_cast<T*>(this);
};

BaseClass * GetBase()
{
    return this;
}
};

class MiddleClass : public BaseClass
{
public:
MiddleClass(){}
virtual ~MiddleClass() {}
};


class TopClass : public MiddleClass
{
public:
TopClass(){}
virtual ~TopClass() {}
};


int __stdcall WinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd )
{
TopClass * t = new TopClass();
MiddleClass * m = static_cast<MiddleClass*>(t);
BaseClass * b = static_cast<BaseClass*>(t);


TopClass * top = m->GetTop();
TopClass * top2 = b->GetTop();

return 0;
}

非常感谢你的想法:)

2 个答案:

答案 0 :(得分:1)

也许你想做一个dynamic_cast&lt;&gt;

您可能希望C ++的行为类似于某些语言,例如C#。事实并非如此 这是另一个类似的帖子。

http://stackoverflow.com/questions/3049404/apples-oranges-and-pointers-to-the-most-derived-c-class

你可能会问一些它没有的C ++。

class basex
{
    public:
    virtual ~basex() {};
};
class middlex : public basex
{
    public:
    //middlex() = default;
};
int dynamic_test()
{
    basex * cbq = new middlex;
    basex * cbq2 = new basex;
    middlex * mcp = dynamic_cast<middlex *>(cbq);
    //should suceed
    if (nullptr != mcp)
    {
        cout << "dynamic cast worked" << endl;
    }
    else
    {
        cout << "dynamic cast failed" << endl;
    }
    //should fail
    middlex * mcp2 = dynamic_cast<middlex *>(cbq2);
    if (nullptr != mcp2)
    {
        cout << "dynamic cast worked" << endl;
    }
    else
    {
        cout << "dynamic cast failed" << endl;
    }
    return 0;
}

您似乎真的想要进行简单的强制转换,而成员函数似乎并不实用

.....................

template < class T >
T* GetTop()

需要改进 它只是做一个演员......而演员需要目的地类型 static_cast需要显式类型参数 从而.. GetTop需要显式类型参数

共达 是一个成员函数... T可以是任何类...提供的代码..没有给定的类型推导参数...你提供的指针是... C ++这...所以你可以只调用它TopClass或派生对象。 (让我们排除复杂的演员阵容)

TopClass * top = m->GetTop();

编译器会尝试理解右侧.............不考虑左侧
编译器不考虑左侧的类型扣除..没有任何类型扣除的帮助..它只是试图理解右侧
我这样说是因为你似乎可能认为编译器会使用类型TopClass进行类型推导......它不会

这将有效编译

TopClass * top = m->GetTop<TopClass>();

但它只是一个显式的static_cast

也许你应该陈述你打算做什么

答案 1 :(得分:1)

您当然可以编写一个成员函数,通过引用参数返回已转换的指针:

template<typename T>
void getTop(T*& result) { result=static_cast<T*>(this); }

您的示例应用程序将如下所示:

TopClass * t = new TopClass();
MiddleClass * m = static_cast<MiddleClass*>(t);
BaseClass * b = static_cast<BaseClass*>(t);


TopClass * top(nullptr);  m->getTop(top);
TopClass * top2(nullptr); b->getTop(top2);

您是否最终有更多或更少的时间编写代码,以及这是否比您当前的课程版本更具可读性,取决于您的特定代码。

编辑:一个简单的扩展版本将是:

template<typename T>
T*& getTop(T*& result) { 
    result=static_cast<T*>(this); 
    return result;
}

TopClass * top=m->getTop(top);
TopClass * top2=b->getTop(top2);

我不知道该解决方案在性能方面与前一个解决方案的比较