настройка доступа унаследованных функций - PullRequest
0 голосов
/ 25 марта 2012

с C #, Java или C ++ ...

у нас есть следующие классы

class A
{
  void x(){y();}
  void y(){}
}

class B :A
{
   void y(){};
   void a(){x();}
}

//in main or somewhere 
B b=new B();
b.a();

, когда вызывается функция "a", она вызовет базовую функцию "x", вопросесть, какую функцию вызовет функция "x" (base y () / производный y ())?и как мы можем контролировать, какой из них вызывать !!

примечание: возьмите концепцию, я знаю, что три языка не совпадают.

Ответы [ 3 ]

2 голосов
/ 25 марта 2012

Ваш код не является допустимым C ++, но если вы сказали B * b = new B; b->a();, то будет вызван A::y(), потому что это не virtual. В Java все нестатические функции-члены неявно являются виртуальными, поэтому здесь вызывается B::y().

Кстати, ваш вопрос очень вводит в заблуждение, поскольку «доступ» - это нечто совершенно иное (относящееся к public и private и т. Д.). В этом отношении код не будет компилироваться ни на одном языке, поскольку B::a() не является public.

2 голосов
/ 25 марта 2012

То, что будет делать этот пример кода, очень зависит от языка, который вы здесь используете.Ваш вопрос упоминает C # / C ++ и Java здесь, и они будут отличаться для вышеуказанного базового шаблона.

C # и C ++ здесь довольно похожи, так как функции не являются виртуальными по умолчанию.Следовательно, вызов x() в x() будет ссылаться на A::x.В Java, хотя методы являются виртуальными по умолчанию, следовательно, он будет ссылаться либо на A::y, либо на B::y, в зависимости от фактического типа this.

Вот пример на всех 3 языках, чтобы сделать y() виртуальным вызовом

C ++

class A {
public:
  void x(){ y(); }
  virtual void y(){}
};

class B : public A {
public:
  // virtual not needed here but nice
  virtual void y() { }; 
  void a() { x(); }
};


B* b = new B();
b->a();

C #

class A {
  public void x(){ y(); }
  public virtual void y(){}
}

class B : public A {
  public overrides void y() { }; 
  public void a() { x(); }
};


B b = new B();
b.a();

Java

class A {
  public void x(){ y(); }
  public void y(){}
}

class B : inherits A {
  public void y() { }; 
  public void a() { x(); }
};

B b = new B();
b.a();
2 голосов
/ 25 марта 2012

(при условии, что вы хотели объявить все как общедоступные и использовать соответствующий синтаксис для каждого языка)

В Java и C # он будет вызывать B :: y.

В C ++ он будет вызывать A :: y.

В C ++, если вы объявили A :: y как virtual , вместо этого будет вызван B :: y.

Реализация статической диспетчеризации (A :: y) более производительна, чем динамическая диспетчеризация (B :: y), поэтому опция в C ++ остается открытой для выбора между ними (виртуальными или не виртуальными). Для Java и C # разработчики языка решили сохранить его простым и разрешить только динамическую диспетчеризацию, поэтому в этих двух языках нет способа сделать статическую диспетчеризацию (A :: y).

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