我尝试动态地将一个根对象引用转换为子类对象引用。我认为有非常正常的逻辑。但出乎意料的是,子类copy-constract函数已被调用。在macosx平台中,相同性测试用例执行正确。 为什么!我想知道原因。可能是视觉工作室2015的一个错误。
class IObject
{
public:
IObject()
{}
IObject(const IObject &ins)
{
}
virtual ~IObject()
{}
};
class CObject : public IObject
{
public:
CObject()
{}
CObject(const CObject &ins)
{
std::cout << "CObject copy constract function has be call" << std::endl;
}
virtual ~CObject()
{}
};
int main(int argc, _TCHAR* argv[])
{
CObject *pCObject= new CObject();
IObject *pIObject = pCObject;
CObject &objectRef = dynamic_cast<CObject*>(pIObject) == NULL ? throw std::exception() : dynamic_cast<CObject&>(*pIObject);
return 0;
}
如下所示是我的测试环境和结果。
测试环境:visual studio 2015,windows 10 64bit 程序语言:C ++ 测试结果:CObject复制constract函数被调用。
测试环境:Xcode 7,Macosx 程序语言:C ++ 测试结果:CObject copy constract函数不能被调用。
答案 0 :(得分:0)
你知道这个简单的行
CREATE TRIGGER [dbo].[Trigger]
ON [dbo].[user]
AFTER DELETE
AS
DECLARE @user_id INT
SELECT @user_id = (SELECT userid FROM DELETED)
BEGIN
DELETE FROM userHouse WHERE userid = @user_id;
END
已经进行了正在编写的运行时检查,如果失败则抛出CObject &objectRef = dynamic_cast<CObject&>(*pIObject);
。
不要重新发明轮子。
您的代码符合标准,似乎MSVC未能从第5.16节正确实施此规则:
如果第二个或第三个操作数的类型为void,则以下之一应保持:
- 第二个或第三个操作数(但不是两个)是一个(可能带括号的)throw-expression(5.17);结果是另一个的类型和值类别。条件表达式是位字段if 该操作数是一个位字段。
- 第二个和第三个操作数都有类型void;结果是void类型,是一个prvalue。 [注意:这包括两个操作数都是throw-expressions的情况。 - 尾注]
因为MSVC没有保留另一个操作数的值类别,所以它将它复制到临时值。
另一种解决方法是
bad_cast_exception