c++ - 在 C++ 中,方法的"virtuality" 是隐式传播的?

  显示原文与译文双语对照的内容
0 0

删除的方法功能更为强大的能力虚拟性的原因是什么?

让我非常清楚 在C++中,不管你写" virtual void foo( ) " 或" void foo( ) " 在派生类中,则将虚拟只要在基类foo被声明为virtual 。

这意味着调用foo( ) 通过derived*指针将导致虚拟表查找( 以防derived2函数重写foo ),即使这种行为并未予以通缉程序员。

我给你举个例子( 对我看起来很明显) 时非常有用如何停止虚拟世界里传播:

template <class T>
class Iterator // Here is an iterator interface useful for defining iterators
{              // when implementation details need to be hidden
public:
    virtual T& next() { ... }
    ...
};
template <class T>
class Vector
{
public:
    class VectIterator : public Iterator<T>
    {
    public:
        T& next() { ... }
        ...
    };
    ...
};

在上例中,Iterator基类可用于实现的一种形式" 类型擦除" 中更加更加清晰,Object Oriented方式。 ( 参见 http://www .artima .com/cppsource/type_erasure 。html 的范例类型擦除。)

但仍可能发现,在我的例子中一个直接可以使用Vector::VectIterator对象( 大多数情况下) 才能访问真实对象而不使用接口。

如果虚拟世界里没有被传播,甚至调用Vector::VectIterator::next( ) 从指针或引用就不会虚拟而又能够被内联和高效运行,仿佛为Iterator接口不存在。

时间:原作者:6个回答

0 0

C++11添加了上下文关键字 final来实现这种效果。

class VectIterator : public Iterator<T>
{
public:
    T& next() final { ... }
    ...
};
struct Nope : VecIterator {
    T& next() { ... } // ill-formed
};
原作者:
0 0

simple snswer是: 不混合使用具体和抽象接口 ! 最明显的方法你hararchive中使用非 virtual- 事务中不能使用高级函数. next()它委托给一个 virtual函数,e .g 。 do_next(). 派生类将覆盖 do_next()可能委托给非 virtual- 事务中不能使用高级函数. next(). 以来, next()函数可能会 inline没有任何成本所涉及的委派。

原作者:
0 0

在我看来此复制的理由之一是 virtual析构函数 在C++时搞错了基类 virtual方法应该定义析构函数 virtual. 这是因为某些代码可能有一个基类的指针,实际上是指向派生类,然后尝试删除this指针( 参阅以下问题详) 。? 通过基类中的析构函数定义为 vritual可以确保所有基类的指针指向派生类( 在任何级别的继承) 将删除正常。

原作者:
0 0

我觉得要移除的原因,是一定会很混淆虚拟世界里通过一个继承结构( I 有技巧性的复杂性的例子如下) 。

但是如果你的问题是删除一些虚拟调用微优化,这样我就不用担心 只要内联虚拟子方法代码以及你周围的迭代器传递通过值而不是引用,很优化编译器将正在能够看到在编译时动态类型和内嵌就只为了你,而不管它是否一个虚方法 !

但是出于完整性的考虑,请看下面的使用的语言,你可以de virtualize:

class A
{
public:
    virtual void Foo() { }
};
class B : public A
{
public:
    void Foo() { } // De-virtualize
};
class C: public B
{
public:
    void Foo() { } // not virtual
};
void F1(B* obj)
{
    obj->Foo();
    static_cast<A*>(obj)->Foo();
}
C test_obj;
F1(test_obj);   // Which two methods are called here?

同时还必须明确的规则添加的方法会被调用,但从一个人到另一个人的选择应该是多种多样的。 只简单得多的传播virtualness方法。

原作者:
...