Можете ли вы переопределить частные функции, определенные в базовом классе? - PullRequest
5 голосов
/ 12 ноября 2011

Полагаю, derived class может override только те функции, которые он унаследовал от base class.Верно ли мое понимание ??

То есть, если у базового класса есть открытая функция-член, скажем, func, то производный класс может override функция-член func.

Ноесли базовый класс имеет закрытую функцию-член, скажем foo, то производный класс не может переопределить функцию-член foo.

Прав ли я?

Редактировать

Я придумала пример кода после изучения ответов, данных членами SO.Я упоминаю пункты, которые я изучал, как комментарии в коде.Надеюсь, я прав.Спасибо

/* Points to ponder:
   1. Irrespective of the access specifier, the member functions can be override in base class.
      But we cannot directly access the overriden function. It has to be invoked using a public
      member function of base class.
   2. A base class pointer holding the derived class obj's address can access only those members which
      the derived class inherited from the base class. */

#include <iostream>

using namespace std;


class base
{
   private:
      virtual void do_op()
      {
         cout << "This is do_op() in base which is pvt\n";
      }

   public:
      void op()
      {
         do_op();
      }
};

class derived: public base
{
   public:
      void do_op()
      {
         cout << "This is do_op() in derived class\n";
      }
};

int main()
{
   base *bptr;
   derived d;

   bptr = &d;
   bptr->op(); /* Invoking the overriden do_op() of derived class through the public 
               function op() of base class */ 
   //bptr->do_op(); /* Error. bptr trying to access a member function which derived class 
                    did not inherit from base class */            

   return 0;
}

Ответы [ 6 ]

10 голосов
/ 12 ноября 2011

Но если базовый класс имеет закрытую функцию-член, скажем, foo, то производный класс не может переопределить функцию-член foo.

В Java вы не можете. В C ++ вы можете.

10 голосов
/ 12 ноября 2011

Вы можете переопределить функции независимо от спецификаторов доступа.Это также сердце не виртуального интерфейса идиома.Единственное требование, конечно, что они virtual.

3 голосов
/ 12 ноября 2011

Вы правы в том, что для переопределения функции в производном классе она должна наследовать ее от базового класса (кроме того, функция базового класса должна быть виртуальной).Однако вы ошибаетесь в своем предположении, что виртуальные функции не наследуются.Например, следующее работает хорошо (и фактически является известной идиомой для проверки предусловия / постусловия):

class Base
{
public:
  void operate_on(some thing);
private:
  virtual void do_operate_on(some thing) = 0;
};

void Base::operate_on(some thing)
{
  // check preconditions
  do_operate_on(thing);
  // check postconditions
}

class Derived: public Base
{
  // this overrides Base::do_operate_on
  void do_operate_on(some thing);
};

void Derived::do_operate_on(some thing)
{
  // do something
}

int main()
{
  some thing;
  Base* p = new Derived;

  // this calls Base::operate_on, which in turn calls the overridden
  // Derived::do_operate_on, not Base::do_operate_on (which doesn't have an
  // implementation anyway)
  p->operate_on(thing);

  delete p;
}

Чтобы увидеть, что частные методы действительно наследуются, нужно посмотреть на сообщения об ошибках, сгенерированныеследующий код:

class Base
{
private:
  void private_method_of_B();
};

class Derived:
  public Base
{
};

int main()
{
  Derived d;
  d.private_method_of_B();
  d.method_that_does_not_exist();
}

Попытка скомпилировать это с помощью g ++ приводит к следующим сообщениям об ошибках:

privatemethodinheritance.cc: In function 'int main()':
privatemethodinheritance.cc:4: error: 'void Base::private_method_of_B()' is private
privatemethodinheritance.cc:15: error: within this context
privatemethodinheritance.cc:16: error: 'class Derived' has no member named 'method_that_does_not_exist'

Если класс Derived не наследует эту функцию, сообщение об ошибкеодинаковые в обоих случаях.

0 голосов
/ 30 августа 2013

Нет. Вы не можете переопределить любую функцию в базовом классе. Моя причина для этого понятия состоит в том, что если вы определяете функцию в производном классе, которая имеет такую ​​же сигнатуру функции в базовом классе, функция базового класса станет скрытой для производного класса.

Для получения дополнительной информации об этой захватывающей проблеме просто посетите: http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Foverload_member_fn_base_derived.htm

0 голосов
/ 12 ноября 2011

Это также зависит от типа наследования
class Derived : [public | protected | private] Base { };

0 голосов
/ 12 ноября 2011

Чтобы переопределить функцию, унаследованную от базового класса, она должна быть и virtual, и классифицироваться как public или protected.

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