c – 如何从基类转换为派生类?

我想创建一个多线程模型,其中服务器主循环不会被挂起的数据库事务停止.所以我做了一些简单的类,这是一个非常简化的版本:

enum Type
{
    QueryType_FindUser      = 1 << 0,
    QueryType_RegisterUser  = 1 << 1,
    QueryType_UpdateUser    = 1 << 2,
    //lots lots and lots of more types
};

class Base
{       
public:
    Type type;
};
class User: public Base
{   
public:
    std::string username;
    User(std::string username)
        :username(username)
    {type = QueryType_FindUser;}        
};

现在,当我将数据作为Base传输时,我想再次将其转换回User类:

concurrency::concurrent_queue<QueryInformation::Base> BackgroundQueryQueue;
void BackgroundQueryWorker::Worker()
{
    while(ServerRunning)
    {
        QueryInformation::Base Temp;
        if(BackgroundQueryQueue.try_pop(Temp))
        {
            switch(Temp.type)
            {
                case QueryInformation::Type::QueryType_FindUser:
                {
                    QueryInformation::User ToFind(static_cast<QueryInformation::User>(Temp));//error here
                    //do sql query with user information
                    break;
                }
                //etc
            }
        }
        boost::this_thread::sleep(boost::posix_time::milliseconds(SleepTime));
    }
}

在我标记// errorhere行的地方,它表示没有用户定义的从Base到User的转换,我该怎么办?如何定义此转换?

我是多态的新手,所以另外解释为什么这不编译也会很棒:)
根据我对多态性的理解,它应该可以在base< - >派生之间*转换.

解决方法:

您只能通过使用指针或引用来使用多态,而不能使用直接值.

因此,你应该使用:

QueryInformation::User * user = static_cast<QueryInformation::User *>(&Temp);

并相应地修改您的代码以使用指针而不是直接值.

此外,你分配Temp的方式,它确实是类Base,而不是类User,因此它的“type”不是QueryType_FindUser,然后static_cast将不会被执行(你不会输入case值).

多态与static_cast的正常使用应如下所示:

QueryInformation::Base * temp = new QueryInformation::User; 
// or obtain by some other methods, so that you don't know the exact
// type, but anyway you *must* use a pointer (or reference).

switch(temp->type)
{
case QueryInformation::Type::QueryType_FindUser:
    {
        QueryInformation::User * user = static_cast<QueryInformation::User*>(temp);
    }
}

在您的情况下,这意味着而不是:

concurrency::concurrent_queue<QueryInformation::Base> BackgroundQueryQueue;

你应该(注意指针):

concurrency::concurrent_queue<QueryInformation::Base *> BackgroundQueryQueue;

正如Mats建议的那样,调用Base的虚拟方法可能会更好,它将自动执行调度,而不是创建自己的交换机并手动创建static_cast.

上一篇:C中的转换函数指针


下一篇:php – Laravel多态关系:将模型传递给控制器