C ++: доступ к родительским методам и переменным - PullRequest
11 голосов
/ 24 декабря 2010

Каким образом я должен получить доступ к этому родительскому методу и родительской переменной?

class Base
{
public:
    std::string mWords;
    Base() { mWords = "blahblahblah" }
};

class Foundation
{
public:
    Write( std::string text )
    {
        std::cout << text;
    }
};

class Child : public Base, public Foundation
{
    DoSomething()
    {
        this->Write( this->mWords );
        // or
        Foundation::Write( Base::mWords );
    }
};

Спасибо.

Редактировать: А что, если есть неясность?

Ответы [ 3 ]

11 голосов
/ 24 декабря 2010

Два синтаксиса, которые вы используете в своем коде (this->... и квалифицированные имена), необходимы только специально, когда есть неоднозначность или какая-то другая проблема поиска имен, такая как скрытие имени, базовый класс шаблона и т. Д.

Когда нет двусмысленности или других проблем, вам не нужен ни один из этих синтаксисов. Все, что вам нужно, это простое неквалифицированное имя, например Write в вашем примере. Просто Write, а не this->Write и не Foundation::Write. То же относится и к mWords.

т.е. в вашем конкретном примере простая Write( mWords ) будет работать нормально.


Чтобы проиллюстрировать вышеизложенное, если ваш метод DoSomething имел параметр mWords, как в

DoSomething(int mWords) {
  ...

тогда этот локальный mWords параметр будет скрывать унаследованный член класса mWords, и вам придется использовать либо

DoSomething(int mWords) {
  Write(this->mWords);
}

или

DoSomething(int mWords) {
  Write(Foundation::mWords);
}

чтобы правильно выразить свое намерение, т.е. прорваться сквозь укрытие.


Если у вашего Child класса также есть свой mWords член, как в

class Child : public Base, public Foundation
{
  int mWords
  ...

тогда это имя будет скрывать унаследованное mWords. Подход this->mWords в этом случае не поможет вам отобразить правильное имя, и вам придется использовать квалифицированное имя для решения проблемы

DoSomething(int mWords) {
  Write(Foundation::mWords);
}

Если оба ваших базовых класса имели член mWords, как в

class Base {
public:
  std::string mWords;
  ...
};

class Foundation {
public:
  int mWords;
  ...

тогда в Child::DoSomething имя mWords будет неоднозначным, и вам придется сделать

DoSomething(int mWords) {
  Write(Foundation::mWords);
}

для устранения неоднозначности.


Но, опять же, в вашем конкретном примере, где нет двусмысленности и нет имени, скрывающего все это, совершенно не нужно.

0 голосов
/ 24 декабря 2010

Поскольку нет конфликта имен, просто используйте Write(mWords).Используйте другие 2, если у вас есть локальные переменные, которые конфликтуют, или когда имена скрыты.

0 голосов
/ 24 декабря 2010

Я думаю, что это наиболее распространенный подход:

Write(mWords);

, если вы не столкнетесь с двусмысленностью.

Если есть двусмысленность или затенение, потому что вы хотите что-то в (определенном) базовом классе, ночто-то в другом базовом классе (или этом классе) скрывает это, затем используйте синтаксис Base::name.

Если локальная переменная скрывает одного из ваших членов, тогда используйте this->, хотя в целом вам следует попробоватьчтобы избежать этой ситуации.(то есть: старайтесь избегать именования местных жителей, чтобы они были теневыми членами)

Я полагаю, что один из способов взглянуть на это - использовать первый из них, который работает и делает то, что вы хотите:

  1. name
  2. this->name
  3. Base::name
...