【发布时间】:2014-08-09 19:44:16
【问题描述】:
背景信息:这是在 Visual Studio 2008 上检测到的,并在 Visual Studio 2013 上再次确认。G++ 对代码大喊大叫,而 Visual 默默接受了私有继承漏洞。
所以,在 Visual C++ 上,我们有以下代码:
class Base {};
class Derived : Base {}; // inherits privately. Adding explicitly the
// keyword private changes nothing
int main()
{
std::auto_ptr<Base>(new Derived) ; // compiles, which is NOT EXPECTED
std::auto_ptr<Base> p(new Derived) ; // Does not compile, which is expected
}
为什么第一个(临时)auto_ptr 会编译?我在调试时进入了它,它完全按照公共继承应该做的事情(调用正确的构造函数等)
想知道问题是否与 auto_ptr 实现有关(我们永远不知道...),我减少了这个独立代码的问题:
class Base {};
class Derived : Base {};
template <typename T>
class Ptr
{
T * m_p;
public :
Ptr(T * p_p)
: m_p(p_p)
{
}
} ;
int main()
{
Ptr<Base>(new Derived) ; // compiles, which is NOT EXPECTED
Ptr<Base> p(new Derived) ; // Does not compile, which is expected
}
再次,我希望代码不会编译,因为 Derived 是从 Base 私有继承的。
但是当我们创建一个临时的,它就起作用了。
我们不能把它归咎于 std::auto_ptr。
我错过了标准中的某些内容(98 或 11 或 14),还是这是一个错误?
【问题讨论】:
-
我的猜测是
Ptr<Base>(new Derived);不像它看起来那样做。看起来它创建了一个使用new Derived构造的临时类型Ptr<Base>,但它实际上声明了一个函数或一些类似的废话。 -
@nwp:这很容易验证,只需从
Derived构造函数和析构函数中打印一些内容,就可以检查是否有实际代码执行。 -
这个bug是一个类似的编译器错误,但是
static_cast:connect.microsoft.com/VisualStudio/feedback/details/540343/… -
FWIW,您甚至不需要模板来生成错误。
class Ptr内部带有硬编码的Base会产生相同的行为。 -
或者更精简的例子:
class Base {}; class Derived : Base {}; struct S { S(Base *) {} }; int main() { S(new Derived); }
标签: c++ visual-studio private-inheritance