Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;允许多层次的虚拟性?_C++_Oop_Inheritance_Polymorphism_Virtual - Fatal编程技术网

C++ C++;允许多层次的虚拟性?

C++ C++;允许多层次的虚拟性?,c++,oop,inheritance,polymorphism,virtual,C++,Oop,Inheritance,Polymorphism,Virtual,我有一个叫做Object的基类。PhysicsObject继承自对象。球继承自PhysicsObject,垒球继承自Ball。大概是这样的: Object | PhysicsObject | Ball | SoftBall 我有一个名为foo()的方法,它在Object中声明为virtual(给定了一个实现,所以不是纯virtual),然后在physicobject和Ball中再次声明并实现为virtual。最后,垒球再次实现foo(),而不将其声明为虚拟 如果我有一个指向垒球的对象*,

我有一个叫做Object的基类。PhysicsObject继承自对象。球继承自PhysicsObject,垒球继承自Ball。大概是这样的:

Object
 |
PhysicsObject
 |
Ball
 |
SoftBall
我有一个名为foo()的方法,它在Object中声明为virtual(给定了一个实现,所以不是纯virtual),然后在physicobject和Ball中再次声明并实现为virtual。最后,垒球再次实现foo(),而不将其声明为虚拟

如果我有一个指向垒球的对象*,会调用垒球版本的foo()吗?如果没有,有没有办法达到这个效果?基本上,多态性的这一方面仍然适用于多个继承级别吗

如果我有一个指向垒球的对象*,会调用垒球版本的foo()吗?如果没有,有没有办法达到这个效果?基本上,多态性的这一方面仍然适用于多个继承级别吗

如果相应的重载在基类中是虚拟的,则C++将方法定义为虚拟的(与其他OO语言不同,在其他OO语言中,重写必须明确标记)


请注意,再加上一些配料,你会变得非常时髦:

#include <iostream>

struct A { virtual void foo() { std::cout << "A::foo();" << std::endl; } };
struct B { virtual void foo() { std::cout << "B::foo();" << std::endl; } };

struct Oa: A, B { using A::foo; };
struct Ob: A, B { using B::foo; };

#define TEST(a) std::cout << #a << ":\t"; a

int main()
{
    A a;
    B b;
    Oa oa;
    Ob ob;

    TEST(a.foo());
    TEST(b.foo());
    TEST(oa.foo());
    TEST(ob.foo());

    std::cout << "But oa through different references:" << std::endl;
    {
        A& ar = oa;
        TEST(ar.foo());

        B& br = oa;
        TEST(br.foo());
    }

    std::cout << "And ob through different references:" << std::endl;
    {
        A& ar = ob;
        TEST(ar.foo());

        B& br = ob;
        TEST(br.foo());
    }

    return 0;
}
#包括

struct A{virtual void foo(){std::cout如果在基类中声明一个虚拟函数,并在派生类中声明一个具有相同签名的函数,它将自动变为虚拟函数(即使中间有任意数量的类层)
将被调用

但是,请注意,如果签名中存在任何差异,则虚拟函数将被隐藏。例如:

class Object {
public:
  virtual void foo();
};

class InBetween : public Object {
  // assume it has no foo()s
};

class A : public InBetween {
public:
  void foo() const; // DOES NOT OVERRIDE; ((Object *)pA)->foo() calls Object::foo()
                    // However pA->foo() calls this
};

class B: public InBetween {
public:
  void foo() const; // Does not override; pB->foo() calls this if pB is const
  void foo(); // Does override; ((Object *)pB)->foo() calls this. pB->foo() also calls this if pB is non-const
};
如果我有一个指向垒球的物体,垒球的 可以调用foo()的版本吗?如果不能,有什么方法可以实现吗 影响?基本上,多态性的这一方面仍然有效吗 不止一个继承级别

当然,…)


下面是我的测试用例(假设
cout
在范围内):

struct对象{
虚拟void foo(){}
};
结构物理对象:对象{};
结构球:PhysicsObject{};
结构垒球{
虚拟void foo(){
coutfoo();
}
//输出:“垒球”

基本上,“基类”是指“任何基类”(这才是问题的重点)添加了更多的背景,虽然基本上是脱离主题的哈哈哈……“文明”?“不错”?“小”?“被亲切提及”?!你没有脱离主题;你脱离了你的大理石;)绝对正确。我发布这个问题是因为我有一个项目(一个突破性克隆)这样设置,但其功能似乎多态性的这一方面不起作用。所以现在我知道问题出在我写的东西上,而不是语言的限制:D@Lewis:*点头*明白。见证一下将问题简化为简单测试用例以缩小问题范围的能力:)顺便说一句,在这种情况下,我怀疑您无意中在某个点切割了对象,或者(我认为可能性较小)由于签名不匹配,您的覆盖实际上不是覆盖。
struct Object {
   virtual void foo() {}
};

struct PhysicsObject : Object {};
struct Ball : PhysicsObject {};

struct SoftBall : Ball {
   virtual void foo() {
      cout << "SoftBall";
   }
};

int main() {
   SoftBall sb;
   Object* o = &sb;
   o->foo();
}

// Output: "SoftBall"