如何从基类中获得顶级

How to get top class from base class

本文关键字:基类      更新时间:2023-10-16

这是我的示例代码。我想从基层或中产阶级中获得一流的。我该怎么做?我不想在任何地方指定顶级类名,我知道我可以写"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;
}

非常感谢您的想法:)

也许您想做一个dynamic_cast<>

您可能希望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需要显式类型参数

GetTop是成员函数。。。T可以是任何类。。。提供的代码。。没有用于类型推导的给定参数。。。你提供的指针是。。。C++这个。。。因此,您可以仅将其称为TopClass或派生对象。(排除复杂铸件)

TopClass * top = m->GetTop();

编译器将尝试理解右侧。。。。。。。。。。。。。不考虑左侧
编译器不考虑类型推导的左侧。。类型推导没有任何帮助。。它只是试图理解右侧
我这么说是因为你可能相信编译器会使用类型TopClass进行类型推导。。。它不会

这将工作编译

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

但它只不过是一个显式的static_cast

也许你应该说明你打算做什么

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

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);

我不知道该解决方案在性能方面与前一个解决方案相比如何