我正在看MVA's tutorial on 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;
};
当我从构造函数中移除std::string
initial_name以及代码编译_name{initial_name}
时。请解释我,不要把我当作经验丰富的高级程序员。我昨天才开始使用C ++。
答案 0 :(得分:11)
tl; dr :Kate的答案中的解决方案适用于OP;解释不正确。有问题的代码实际上是正确的,并且在VS2015中编译。错误(在VS2013 Update 3 中)是MS如何处理在VS2013 RTM中发现的错误的结果(他们没有通过更新实际修复它,但他们确实打破了一些工作码)。它已在VS2015中正确修复。
您的代码在VS2015中运行良好。 According to Microsoft,在VS2013中,
是的,我们在Update 3中将这些错误插入到编译器中,因为我们对非静态数据成员初始化的实现不完整。
成员初始化列表中的列表/支撑初始化在VS2013中也被破坏。它们的实现问题是illustrated best 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 &)'
};
编译器很容易回退到正常的重载分辨率。它不是使用std::initializer_list
构造函数,而是调用size_t
构造函数。正如他们的评论所示,这是错误的!因此,由于它们的实现存在缺陷,Microsoft决定禁用在此上下文中使用支撑初始化的功能。
对于std::string s
,应该没有问题,因为s{"duh"}
正确来调用std::string(const char*)
,但由于该缺陷,MS给出了无论如何都是错误的。解决方法是明确使用括号代替大括号(或升级到VS2015),如Kate的答案中所述。但错误的正确原因如上所述。
这适用于非静态数据成员初始化(NSDMI)以及初始化列表。这在Visual C++ Team Blog中有更多解释。至于为什么VS2013永远不会修复:
我们最初计划在Visual Studio 2013的更新中修复此错误,但从工程角度来看,正确的做法是避免另一个问题,并彻底解决初始化的处理问题。但是,由于需要修改的基本代码量,检修编译器架构是一项艰巨的任务。我们无法冒险在更新中创建不兼容性或大错误尾部,因此NSDMI的正确实现只能在主要版本中发布。
显然,修复程序已进入Visual Studio 2015,但永远不会更新到2013年。
答案 1 :(得分:7)
在James和我编写用于MVA日和今天的代码之间有一个编译器更改。发生了什么
_name{ initial_name }
被解释为创建一个初始化列表,其中包含一个项目并使用它来初始化成员变量。你不能这样做。
修复方法是切换到圆括号:
_name(initial_name)
这引起了许多人的混淆,而且我至少有一个客户端为此破坏了工作代码。
答案 2 :(得分:-4)
我解决了。
class Namedrectangle : public Rectan
{
public:
Namedrectangle(){}
Namedrectangle(string intname, int init_width, int init_height)
: Rectan{ init_width, init_height }
{
this->_name=intname;************
}
string get_name() const
{
return _name;
}
private:
string _name;
};
我认为无法初始化因为变量无法找到或加载