heh*_*ehe 3 c++ inheritance visual-studio visual-studio-2013
我正在观看MVA关于C++的教程,我在下面提到的代码是由凯特写的而不是我.然而,她似乎没有编译显示任何错误,但在我的情况下,我得到以下错误:
错误1错误C2797:'NamedRectangle :: _ name':成员初始化列表中的列表初始化或非静态数据成员初始化程序未实现c:\ users\abhimanyuaryan\documents\visual studio 2013\projects\kate demos\17 inheritance\inheritance \namedrectangle.h 12 1继承
代码中的第12行来自我的NameRectangle类继承自Rectangle类:
class NamedRectangle : public Rectangle
{
public:
NamedRectangle() { }
NamedRectangle(std::string initial_name, int initial_width, int initial_height)
: Rectangle{ initial_width, initial_height }, _name{ initial_name } //--> This line
{}
std::string get_name() const { return _name; }
private:
std::string _name;
};
Run Code Online (Sandbox Code Playgroud)
当我std::string从构造函数中删除initial_name以及_name{initial_name}代码编译时.请解释我,不要把我当作经验丰富的高级程序员.我昨天才开始使用C++.
cha*_*pjc 11
tl;博士:凯特答案中的解决方案适用于OP; 解释不正确.有问题的代码实际上是正确的,并且在VS2015中编译.错误(在VS2013 Update 3中)是MS如何处理在VS2013 RTM中发现的错误的结果(他们实际上没有通过更新修复它,但是他们确实破坏了一些工作代码).它在VS2015中正确固定.
您的代码在VS2015中正常运行. 据微软称,在VS2013中,
是的,我们将这些错误插入到Update 3中的编译器中,因为我们对非静态数据成员初始化的实现是不完整的.
在VS2013中,成员初始化列表中的列表/支撑初始化也被中断.它们的实现问题最好用a 来说明vector,它有一个initializer_list构造函数,应该贪婪地匹配任何使用带有可转换参数的大括号的初始化,但它不能这样做:
struct S {
S() : v1{1} {} // C2797, VS2013 RTM incorrectly calls 'vector(size_type)'
std::vector<int> v1;
std::vector<int> v2{1, 2}; // C2797, VS2013 RTM incorrectly calls
// 'vector(size_type, const int &)'
};
Run Code Online (Sandbox Code Playgroud)
编译器很容易回退到正常的重载分辨率.它不是使用std::initializer_list构造函数,而是调用size_t构造函数.正如他们的评论所示,这是错误的!因此,由于它们的实现存在缺陷,Microsoft决定禁用在此上下文中使用支撑初始化的功能.
对于a std::string s,应该没有问题,因为正确的s{"duh"} 是调用std::string(const char*),但由于该缺陷,MS无论如何都会出错.解决方法是明确使用括号代替括号(或升级到VS2015),如Kate的回答中所述.但错误的正确原因如上所述.
这适用于非静态数据成员初始化(NSDMI)以及初始化列表.这个在Visual C++团队博客中有更多解释.至于为什么VS2013永远不会修复:
我们最初计划在Visual Studio 2013的更新中修复此错误,但从工程角度来看,正确的做法是避免另一个问题,并彻底解决初始化的处理问题.但是由于需要修改的基本代码量,检修编译器架构是一项艰巨的任务.我们无法冒险在更新中创建不兼容性或大错误尾部,因此NSDMI的正确实现只能在主要版本中提供.
显然,修复程序已进入Visual Studio 2015,但永远不会更新到2013.
詹姆斯和我编写我们用于MVA日和今天的代码之间有一个编译器更改.发生了什么事
_name{ initial_name }
Run Code Online (Sandbox Code Playgroud)
被解释为创建一个初始化列表,其中包含一个项目并使用它来初始化成员变量.哪个你不能做.
解决方法是切换到圆括号:
_name(initial_name)
Run Code Online (Sandbox Code Playgroud)
这引起了许多人的混淆,我至少有一个客户端,这对他们破坏了工作代码.