【发布时间】:2017-09-17 15:29:45
【问题描述】:
我在 Visual Studio 2013 和 2017 中发现 std::unique_ptr 的行为非常奇怪。让我们考虑一个示例:
class Base
{
public:
virtual ~Base() = default;
virtual void Foo() = 0;
};
class Derived : private Base
{
public:
void Foo() override
{
std::cout << "Foo";
}
};
void Foo(std::unique_ptr<Base> a)
{
a->Foo();
}
Foo(std::unique_ptr<Base>(new Derived())); // Compiles
请注意,继承是私有的。此示例仅在 Visual Studio 上编译。此外,虚函数调用之所以有效,是因为它是公共继承。所以我们有封装违规,因为从Derived 到Base 的转换应该是不可访问的。谁能解释为什么 Visual Studio 允许这样做?这是一个已知问题吗?
出于合理的原因,以下行无法编译。第一种用法和第二种用法的唯一区别在于第二种用法,创建了命名对象B。
std::unique_ptr<Base> B(new Derived()); // Doesn't compile
它是否与 this issue 有某种关系,但仍未修复?
【问题讨论】:
-
我假设这是 C++?如果是这样,请标记它。
-
有趣。我得到了和你一样的结果rextester.com/FAMW65845。不适用于 clang 或 g++
-
奇怪的是,IntelliSense 实际上将此突出显示为错误并显示正确的诊断“转换为无法访问的基类...”
-
这里没有什么奇怪的。 Visual Studio 编译器从未成功地远程使 C++ 正确。
-
这不应该编译 -
Foo(std::unique_ptr<Base>(new Derived())); // Compiles不能出现在函数之外。我建议更新代码以包含 MCVE
标签: c++ visual-studio encapsulation unique-ptr private-inheritance