Защищенные данные в родительском классе, не доступном в дочернем классе?

Помните, стилистические решения практические решения, если Вы когда-нибудь планируете поддержание или отладку Вашего кода :-) Существует известная кавычка от Knuth (возможно заключающий Hoare в кавычки?): "Мы должны забыть о маленькой эффективности, сказать приблизительно 97% времени: преждевременная оптимизация является корнем всего зла".

, пока Вы боитесь (говорить), поворачивают O (n) задача в O (n <глоток> 2 ) задача, я пошел бы с тем, какой бы ни Вы находите самыми легкими понять..

11
задан Paul Nathan 12 September 2009 в 14:29
поделиться

4 ответа

Согласно TC ++ PL, pg 404:

Производный класс может получить доступ к защищенным членам базового класса только для собственных объектов. type .... Это предотвращает незаметные ошибки, которые в противном случае могли бы возникнуть, когда один производный класс искажает данные, принадлежащие другим производным классам.

Конечно, вот простой способ исправить это для вашего случая:

class A
{
protected:
    int data;
};

class B : public A
{
public:
    B(const A &a)
        : A(a)
    {
    }
};

int main()
{
    A a;
    B b = a;
    return 0;
}
10
ответ дан 3 December 2019 в 08:56
поделиться

Вы просто не должны 't копирует объект A в конструктор B . Намерение состоит в том, чтобы оставить инициализацию членов A его собственному конструктору:

struct A { 
  A( const A& a ): data( a.data ) {}
  protected: int data; 
};

struct B : public A {
  B( const A& a ): A( a ) {}
};
1
ответ дан 3 December 2019 в 08:56
поделиться

Стандарт C ++ говорит о защищенных нестатических членах в 11.5 / 1

Когда друг или функция-член производного класса ссылается на защищенную нестатическую функцию-член или защищенную нестатическую элемент данных базового класса, проверка доступа применяется в дополнение к тем, которые описаны ранее в разделе 11. За исключением случаев формирования указателя на член (5.3.1), доступ должен осуществляться через указатель, ссылку или объект сам производный класс (или любой класс, производный от этого класса) (5.2.5). Если доступ предназначен для формирования указателя на член, спецификатор вложенного имени должен называть производный класс (или любой класс, производный от этого класса).

В дополнение к исправлению вещей, упомянутых ранее другими (конструктор B является частным), я думаю, что способ rlbond сделает это нормально. Однако,

2
ответ дан 3 December 2019 в 08:56
поделиться

Конструктор B является частным. Если вы ничего не указываете, в классе модификатор по умолчанию является частным (для структур он общедоступным). Итак, в этом примере проблема заключается в том, что вы не можете построить B. Когда вы добавляете public в конструктор B, возникает другая проблема:

B имеет право изменять часть A, от которой он происходит, но не другой A, как в этом случае.

Вы можете сделать следующее:

class A
{
public:
  A()
      : data(0)
  {
  }
  A(A &a)
  {
    data = a.data;
  }
protected:
  int data;
};

class B : public A
{
public:
  B(A &a)
      : A(a)
  {
  }
};

int main()
{
  A a;
  B b = a;
  return 0;
}
0
ответ дан 3 December 2019 в 08:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: