首页 > 解决方案 > C2440 static_cast 无法从基类转换为派生类

问题描述

我试图理解为什么使用指针从基类转换为派生类编译得很好,但使用非指针对象进行转换会产生错误 C2440。

下面我有一个ThreadedMessage由 class 继承的基类GPSMessage

struct ThreadedMessage
{
  ThreadedMessage()
    : m_Type(0), m_ID(0)
  { }

  ThreadedMessage(uint Type, uint ID = 0) :
    m_Type(Type), m_ID(ID)
  { }

  uint m_Type;
  uint m_ID;
};    

struct GPSMessage : public ThreadedMessage
{
  GPSMessage()
    : ThreadedMessage()
  { }

  GPSMessage(double lat, double lon)
    : ThreadedMessage(1), m_lat(lat), m_lon(lon)
  { }

  double m_lat;
  double m_lon;
};

myFunction我试图从基类转换为派生类。

void myFunction(const ThreadedMessage& msg)
{
  const GPSMessage* message = static_cast<const GPSMessage*>(&msg); // Compiles fine
  const GPSMessage message1 = static_cast<const GPSMessage>(msg);   // Error C2440
}

调用myFunction()看起来像这样:

GPSMessage msg(21.123, 12.321);
myFunction(msg);

当我编译时,指针的转换编译正常,但非指针转换失败并出现以下错误:

错误 C2440:“static_cast”:无法从“const ThreadedMessage”转换为“const GPSMessage”没有构造函数可以采用源类型,或者构造函数重载决议不明确

为什么我无法使用非指针变量从基类转换为派生类?

编译器是 MS VS 2008 C++。

是的,我看过其他类似的 SO 问题,但我读过的那些似乎没有回答我的问题。

标签: c++castingpolymorphismstatic-cast

解决方案


这两个演员有不同的含义。

第一个演员:

const GPSMessage* message = static_cast<const GPSMessage*>(&msg); // Compiles fine

这意味着它msg实际上是一个GPSMessage(或派生的)对象。您要求编译器msgGPSMessage. 不会创建新对象,message将指向msg. 如果msg实际上不是GPSMessage(或派生的),则此转换具有未定义的行为。

顺便说一句,以下转换具有相同的含义(转换为引用):

const GPSMessage& message = static_cast<const GPSMessage&>(msg); // same meaning, which results in a reference instead of a pointer

关于第二个演员:

const GPSMessage message1 = static_cast<const GPSMessage>(msg);   // Error C2440

意味着,您message1msg. 您应该提供一种使这种转换成为可能的方法。例如,您应该创建一个GPSMessage具有ThreadedMessage参数的构造函数:

struct GPSMessage {
    GPSMessage(const ThreadedMessage &); // needed constructor
};

ThreadedMessage或者为to创建一个转换运算符GPSMessage

struct ThreadedMessage {
    operator GPSMessage(); // conversion operator
};

推荐阅读