Visual C++ 中的重大更改
此文档列出了 Visual Studio 2012 中的 Visual C++ 中的重大更改。
Visual C++ 编译器
使用 /clr,在生成的代码,enum class 关键字定义 c. ++11 枚举,而不是公共语言运行时 (CLR) 枚举。 若要定义 CLR 枚举,您必须是显式的有关它的可访问性。 下面的示例说明了这一点。
enum class ArrivalStatus // C++11 scoped enum { Late, OnTime, Early }; private enum class DepartureStatus // CLR enum (because of explicit accessibility) { Late, OnTime, Early }; void PrintStatus(ArrivalStatus arrival, DepartureStatus departure) { Console.WriteLine("Departure: {0}, Arrival: {1}", departure.ToString(), arrival.ToString() // ERROR: not a CLR enum; does not support .ToString() ); }
使用 template 关键字显式消除一个依赖名称 (C++ 语言标准)。 在下面的示例中,显示的模板关键字是必须解析多义性。 有关更多信息,请参见相关类型的名称转换。
template <typename X, typename AY> struct Container { typedef typename AY::template Rebind<X>::Other AX; };
如下面的示例所示,类型 float 常数表达式不再允许作为模板参数。
template<float n> struct B {}; // error C2762: 'float': illegal type for non-type template parameter 'n' template<int n> struct A {}; A<1.1> a1; // error C2762: 'A': invalid expression as a template argument for 'n' A<(int)1.1> a2; // ok
如下面的伪代码示例所示,代码会编译使用 /GS 命令行选项和具有由漏洞可能导致进程终止的运行时。
char buf[MAX]; int cch; ManipulateString(buf, &cch); // ... buf[cch] = '\0'; // if cch >= MAX, process will terminate
x86 生成的默认值体系结构更改为 SSE2;因此,编译器会发出 SSE 命令和使用个 XMM 寄存器执行浮点计算。如果要还原为早期行为,请使用 /arch:IA32 编译器标志指定体系结构作为 IA32。
编译器会发出它在此之前未的警告 C4703 和 C4701。编译器将更强的检查为指针类型的未初始化的局部变量的使用。
当新的链接器标志 /HIGHENTROPYVA 指定时,Windows 8 通常会导致内存分配返回一个 64 位地址。 (在 Windows 8,小于 2 GB。) 这样的分配经常返回的地址之前这可能显示指针在现有代码的截断 bug。默认情况下,此开关打开。若要禁用此行为,请指定 /HIGHENTROPYVA:NO。
托管编译器 (Visual Basic /C#) 还支持托管生成的 /HIGHENTROPYVA。 但默认情况下,在这种情况下,/HIGHENTROPYVA 开关取消。
集成开发环境
下列项目模板不再存在:
Windows 窗体应用程序
Windows 窗体控件库
虽然建议您在 C++/CLI 不创建 windows 窗体应用程序,现有的 C++/CLI UI 应用程序维护支持。 如果必须创建 windows 窗体应用程序、或其他 UI .NET 应用程序、使用 C# 或 Visual Basic。 使用 C++/CLI 仅用于实现互操作性。
Visual C++ 库
并行模式库 (ppl) 和并发运行库
UmsThreadDefault 的 SchedulerType 枚举已弃用。 UmsThreadDefault 的规范生成一个已否决警告和内部映射回 ThreadScheduler。
标准模板库
在 C++98/03 和 C++11 条件之间的重大更改之后,使用显式模板参数调用 make_pair()—在 make_pair<int, int>(x, y)—在 Visual Studio 2012 中的 Visual C++通常不生成。 解决方案将始终调用 make_pair() 没有显式模板参数在 make_pair(x, y)。 提供显式模板参数使该函数的用途。 如果需要对该结果类型的精确的控制,请使用 pair 而不是 make_pair—在 pair<short, short>(int1, int2)。
在 C++98/03 和 C++11 条件之间的另一个重大更改:当隐式转换为 A 和 B 时隐式转换为 C,但是,不会隐式转换到要转换的 C、C++98/03 和 Visual C++ 2010 允许的 pair<A, X> (隐式或显式) 转换为 pair<C, X>。 (另一种类型,X,不感兴趣在 + 这里,这样,不特定于第一个输入匹配。)由于 C++11 和 Visual Studio 2012 中的 Visual C++ 检测不会隐式转换为 C,它们用于加载解析取消对转换。 这是许多方案的正更改。 例如,重载 func(const pair<int, int>&) 和 func(const pair<string, string>&)和调用 func() 与 pair<const char *, const char *> *, 将生成与此更改。 但是,此更换依赖于主动对转换的代码。 此类代码可以执行转换的一部分通常修复显式 (例如,通过 make_pair(static_cast<B>(a), x) 给需要 pair<C, X>的功能。
Visual C++ 2010 模拟了 variadic 模板 (例如,make_shared<T>(arg1, arg2, argN)—到 10 个参数限制,通过灭绝超加载和专用化与预处理器很多。 在 Visual Studio 2012 中的 Visual C++,此限制减少到 5 个参数改进编译时和编译器内存消耗的大多数用户。 但是,可以通过显式定义 _VARIADIC_MAX 设置上述限制为 10,项目。
C++11 17.6.4.3 .1 [宏。 在 C++ 标准库标头包括的时,名称]/2 forbidden 宏 izing 关键字。 在检测到宏 ized 关键字,标头现在发出编译器错误。 (定义 _ALLOW_KEYWORD_MACROS 允许这样的代码生成,但是,我们强烈建议该用法。)默认情况下为异常,使用 #pragma push_macro("new")/#undef new/#pragma pop_macro("new"),,因为标头全面保护自己宏 ized new 允许的。 定义 _ENFORCE_BAN_OF_MACRO_NEW 正确执行的名称提示。
若要实现各种优化和调试检查,标准 C++ 库实现特意中断在 Visual Studio 中的版本的二进制兼容性 (2005,2008,2010,2012)。 当使用时 C++ 标准库,则禁止编译使用不同的版本到一个双重的组合对象文件和静态库 (EXE 或 DLL),并且禁止通过标准 C++ 库对象在使用不同的版本,生成的二进制文件之间。 组合对象文件和静态库 (使用 C++ 标准库) 编译使用与的 Visual C++ 2010 编译使用 Visual Studio 2012 中的 Visual C++ 发出有关 _MSC_VER 不匹配的链接器错误,_MSC_VER 是宏包含编译器的主 (1700 版 Visual Studio 2012 中的 Visual C++)。 此检查检测不到 DLL 组合,并且无法检测到组合这涉及 Visual C++ 2008 或之前。
除了检测 _ITERATOR_DEBUG_LEVEL 不匹配外,在 Visual C++ 2010实现,Visual Studio 2012 中的 Visual C++ 检测 RuntimeLibrary 不匹配。 这些出现问题,则编译器选项 /MT (静态版本),/MTd (静态调试),/MD (动态版本) 和 /MDd (动态调试) 是混合。
operator<()、operator>()、operator<=()和 operator>=() 到容器 std::unordered_map 和 stdext::hash_map 系列是前面提供的,因此,尽管它们的实现实际上是没有意义的。 这些非标准运算符在 Visual Studio 2012 中的 Visual C++中移除。 此外,operator==() 的 std::unordered_map 系列的实现和 operator!=() 被扩展为包括 stdext::hash_map 系列。 (建议您避免使用新的编码 stdext::hash_map 系列。)
C++11 22.4.1.4 [locale.codecvt] 指定 codecvt::length() 和 codecvt::do_length() 应采用可修改的 stateT& 参数,但是,Visual C++ 2010 拍摄 const stateT&。 Visual Studio 2012 中的 Visual C++ 采用 stateT& 根据需要根据该条件。 差异的尝试重写虚函数 do_length()的人非常重要。
CRT 库
C 运行时 (crt) 堆,对于 new 和 malloc()使用,不再是私有的。 CRT 现在使用处理堆。 这意味着销毁堆,当卸载 DLL 时,因此使用 CRT 链接必须确保静态的 DLL DLL 代码分配的内存清理,在卸载之前。
iscsymf() 功能断言与负值。
threadlocaleinfostruct 结构更改为适应对区域设置功能的更改。
具有相应的内部例如 memxxx()的 CRT 函数,strxxx() 从 intrin.h中移除。 如果要包括的仅 intrin.h 这些功能,现在必须包括对应的 CRT 标头。
MFC 和 ATL 库
取消的合成支持 (afxcomctl32.h);因此,在 afxcomctl32.h 定义移除的所有方法。 标头文件 afxcomctl32.h 和 afxcomctl32.inl 已删除。
已更改 CDockablePane::RemoveFromDefaultPaneDividier 的名称。CDockablePane::RemoveFromDefaultPaneDivider。
更改 CFileDialog::SetDefExt 签名使用 LPCTSTR;因此,Unicode 编译受影响。
删除了过时的 ATL 跟踪的类别。
更改 CBasePane::MoveWindow 签名采用 const CRect。
已更改 CMFCEditBrowseCtrl::EnableBrowseButton签名。
已移除的 m_fntTabs 和 m_fntTabsBold 从 CMFCBaseTabCtrl。
添加了一个参数。CMFCRibbonStatusBarPane 构造函数。 (它是默认参数,因此,不源中断。)
添加了一个参数。CMFCRibbonCommandsListBox 构造函数。 (它是默认参数,因此,不源中断。)
移除了 AFXTrackMouse API (及相关计时器进程内)。 使用 Win32 TrackMouseEvent API。
添加了一个参数。CFolderPickerDialog 构造函数。 (它是默认参数,因此,不源中断。)
CFileStatus 已更改的结构范围:m_attribute 成员从字节更改为 DWORD (与从 GetFileAttributes返回) 的值。
CRichEditCtrl 和 CRichEditView 使用 MSFTEDIT_CLASS (RichEdit 4.1 控件) 而不是 RICHEDIT_CLASS (RichEdit 3.0 控件) 在 Unicode 生成。
已移除的 AFX_GLOBAL_DATA::IsWindowsThemingDrawParentBackground,因为始终为 true 在 Windows vista、windows 7 和 windows 8。
已移除的 AFX_GLOBAL_DATA::IsWindowsLayerSupportAvailable,因为始终为 true 在 Windows vista、windows 7 和 windows 8。
已移除的 AFX_GLOBAL_DATA::DwmExtendFrameIntoClientArea。 调用 windows API 直接在 Windows vista、windows 7 和 windows 8。
已移除的 AFX_GLOBAL_DATA::DwmDefWindowProc。 调用 windows API 直接在 Windows vista、windows 7 和 windows 8。
为消除名称冲突的 IsDwmCompositionEnabled 的重命名的 AFX_GLOBAL_DATA::DwmIsCompositionEnabled。
已更改的标识符多种 MFC 内部计时器的和移动定义移到 afxres.h (AFX_TIMER_ID_*)。
更改 OnExitSizeMove 方法签名授予 ON_WM_EXITSIZEMOVE 宏:
CFrameWndEx
CMDIFrameWndEx
CPaneFrameWnd
更改 OnDWMCompositionChanged 名称和签名授予 ON_WM_DWMCOMPOSITIONCHANGED 宏:
CFrameWndEx
CMDIFrameWndEx
CPaneFrameWnd
更改 OnMouseLeave 方法签名授予 ON_WM_MOUSELEAVE 宏:
CMFCCaptionBar
CMFCColorBar
CMFCHeaderCtrl
CMFCProperySheetListBox
CMFCRibbonBar
CMFCRibbonPanelMenuBar
CMFCRibbonRichEditCtrl
CMFCSpinButtonCtrl
CMFCToolBar ReplaceThisText
CMFCToolBarComboBoxEdit
CMFCToolBarEditCtrl
CMFCAutoHideBar
更改 OnPowerBroadcast 签名授予 ON_WM_POWERBROADCAST 宏:
CFrameWndEx
CMDIFrameWndEx
更改 OnStyleChanged 签名授予 ON_WM_STYLECHANGED 宏:
CMFCListCtrl
CMFCStatusBar
给内部方法 FontFamalyProcFonts 重命名为 FontFamilyProcFonts。
取消的许多全局静态 CString 对象消除内存泄漏的在某些情况下 (将替换为 #defines) 和以下选件类成员变量:
CKeyBoardManager::m_strDelimiter
CMFCPropertyGridProperty::m_strFormatChar
CMFCPropertyGridProperty::m_strFormatShort
CMFCPropertyGridProperty::m_strFormatLong
CMFCPropertyGridProperty::m_strFormatUShort
CMFCPropertyGridProperty::m_strFormatULong
CMFCPropertyGridProperty::m_strFormatFloat
CMFCPropertyGridProperty::m_strFormatDouble
CMFCToolBarImages::m_strPngResType
CMFCPropertyGridProperty::m_strFormat
已更改 CKeyboardManager::ShowAllAccelerators 签名并移除快捷键分隔符参数。
添加了 CPropertyPage::GetParentSheet,然后在 CPropertyPage 选件类,所以称之为而不是 GetParent 获得正确的父页窗口,这可能是父或祖父项窗口放置 CPropertyPage。 您可能必须更改您的代码调用 GetParentSheet 而不是 GetParent。
固定平衡 #pragma warning (驱动器) 在 ATLBASE.H,导致警告错误被禁用。 在 ATLBASE.H 分析后,这些警告正确现在已启用。
从 AFX_GLOBAL_DATA 的移动后的 D2D 相关的方法。_AFX_D2D_STATE:
GetDirectD2dFactory
GetWriteFactory
GetWICFactory
InitD2D
ReleaseD2DRefs
IsD2DInitialized
D2D1MakeRotateMatrix
而不是调用例如,afxGlobalData.IsD2DInitialized,请调用 AfxGetD2DState->IsD2DInitialized。
从 \atlmfc\include\ 文件夹中删除了过时的 ATL*.CPP 文件。
对于在需要时的移动后的 afxGlobalData 初始化而不是 CRT 初始化时,满足 DLLMain 要求。
添加了 RemoveButtonByIndex 方法。CMFCOutlookBarPane 选件类。
为 IsFrequentlyUsedCmd的更正了 CMFCCmdUsageCount::IsFreqeuntlyUsedCmd。
更正了 RestoreOriginalstate 多个实例。RestoreOriginalState (CMFCToolBar、CMFCMenuBar,CMFCOutlookBarPane)。
从 CDockablePane中移除的未使用的方法:SetCaptionStyle、IsDrawCaption、IsHideDisabledButtons、GetRecentSiblingPaneInfo和 CanAdjustLayout。
已移除的 CDockablePane 静态成员变量 m_bCaptionText 和 m_bHideDisabledButtons。
添加了重写 DeleteString 方法。CMFCFontComboBox。
从 CPane中移除的未使用的方法:GetMinLength 和 IsLastPaneOnLastRow。
为 CPane::SetDockSiteRow的重命名的 CPane::GetDockSiteRow(CDockingPanesRow *) *)。