Наследование в C ++ и ожидаемое поведение - PullRequest
0 голосов
/ 24 марта 2020

Я работаю над заданием, включающим 4 класса и наследование бриллиантов. Я основал все свои ответы на предположении, что оно может или не может быть правильным.

Алмазная иерархия выглядит следующим образом:

   A
  / \
 B   C
  \ /
   D

и код выглядит следующим образом:

class A
{
private:
   string s;
public: 
   A(string s);
   virtual ~A;
   virtual void set(string s);
   virtual string get();
};

class B : public virtual A
{
public:
 void set(string s);
 string get();
}

class C : public virtual A
{
public:
  void set(string s);
}

class D : public B, public C
{
public:
  void set(string s);
}

Предположим, у меня есть указатель, который выглядит следующим образом: C *obj = new D();

Если get вызывается для obj, указатель фактически завершит цикл до D, а затем вызовет метод get метода B. Один объект C в конечном итоге вызовет метод get класса A. Предполагая, что методы get B и A возвращают разные результаты, какой результат можно ожидать?

Ответы [ 2 ]

1 голос
/ 24 марта 2020

Код, который вы предоставили, к сожалению, не скомпилируется как есть. Мы можем создать подобный пример и просто попробовать его:

#include <cstdio>

struct A
{
  virtual char const * get() {return "a";};
  virtual ~A() = default;
};

struct B : public virtual A
{
  char const * get() override {return "b";};
};

struct C : public virtual A
{
  //char const * get() override {return "c";};
};

struct D : public B, public C
{
  //char const * get() override {return "d";};
};

int main()
{
  A* a = new A();
  B* b = new B();
  C* c = new C();
  C* d = new D();
  printf("%s\n", a->get());
  printf("%s\n", b->get());
  printf("%s\n", c->get());
  printf("%s\n", d->get());
  delete a;
  delete b;
  delete c;
  delete d;
}

, что дает:

a
b
a
b

iso cpp вызывает это делегирование в родственный класс

Поскольку B и C оба фактически наследуют A, существует только один экземпляр A, поэтому в виртуальной таблице, когда B переопределяет реализацию A, только один член переопределяет get, и это также переопределяется для D.

Если вы также раскомментируете метод get в C, тогда мы получим:

virtual.cc:19:8: error: no unique final overrider for 'virtual const char* A::get()' in 'D'
   19 | struct D : public B, public C
      |        

Однако дальнейшая модификация примера, а также раскомментирование get в D приведут к повторной компиляции кода. Сейчас возвращаемся:

a
b
c
d
1 голос
/ 24 марта 2020

Он будет действовать как D объект.

Точно так же, как и при одиночном наследовании, он действует как созданный класс (а не как указатель на него).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...