2013-08-27 2 views
1

У меня есть один базовый класс/родительский класс: PersonКласса ошибка наследования: Частный член

И два подклассы/дочерние классы: Игрок, тренер

Это то, что заголовок для лица, внешнего вида базового класса как:

class Person 
{ 
    public: 
     Person(string name); 
     Person(); 
     virtual ~Person(); 
     string getName(); 
     void setName(string name); 
     virtual void printSpec() const = 0; 

    private: 
     string name; 
}; 

Я пытался скомпилировать и запустить, он начал жаловаться на это:

include\Person.h||In constructor 'Coach::Coach(std::string, std::string)':| 
include\Person.h|19|error: 'std::string Person::name' is private| 
\src\Coach.cpp|5|error: within this context| 
||=== Build finished: 2 errors, 0 warnings ===| 

И указал на это:

private: 
    string name; 

В контексте одной из двух конструкторов для класса ребенка «Тренер»:

Coach::Coach(string name, string responsibility): Person(name){ 
    this->name = name; 
    this->responsibility = responsibility; 
} 

Однако это не делает ту же жалобу о том, что очень той же строкой в ​​конструкторе класса «Player», только жалуется на то, что «имя строки является частным членом» в конструкторе класса «Coach».

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

Что дает?

+1

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

+0

Получите [приличную книгу на C++] (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). 'Player :: name' является закрытым. если вы хотите, чтобы производные классы имели доступ на уровне членов (и в этом случае нет оснований, но это другое дело), ​​он должен быть * protected * или * public * или * friend * -ed (последний очень необычен для производные классы). – WhozCraig

+0

Как вы объявляете класс тренера? (Не забудьте также использовать общедоступное слово) – doctorlove

ответ

4

Доступ к объекту невозможен с помощью класса private.

Решение может быть использование -член инициализацию-лист сделать:

Coach::Coach(string name, string responsibility): Person(name){ 
    //           ^^^^^^^^^^^^ 
    //      Initialize the name through the base class constructor 
    this->responsibility = responsibility; 
} 

Поскольку Person является базового класса и есть конструктор, который принимает имя, вы можете сделать это так. Вам не нужно обращаться к элементу name из производного класса.


Другим решением может быть, чтобы установить этот элемент protected (первое решение все еще лучше).

class Person 
{ 
    public: 
     Person(string name); 
     Person(); 
     virtual ~Person(); 
     string getName(); 
     void setName(string name); 
     virtual void printSpec() const = 0; 

    protected: 
// ^^^^^^^^^ 
     string name; 
}; 

Вы посмотрите here, наследство части разговоров о доступе типа можете.


не ответить на вопрос, но для некоторой хорошей практики, я хотел бы предложить вам передать свой параметр string в качестве const ссылки. Это better practice:

Coach::Coach(const string& name, const string& responsibility): Person(name){ 
    //  ^^^^^  ^  ^^^^^  ^
    this->responsibility = responsibility; 
} 
+0

'Coach' ** ** получен из' Person', поэтому конструктор является правильным подходом. Изменение 'name' на' protected' ** неверно **. Конструктор может инициализировать элемент, а функция 'setName' может использоваться для установки позже, если это необходимо. –

+0

@PeteBecker Вы правы, я редактировал свое сообщение, чтобы сделать его более подходящим. Спасибо за указание на это. –

1

Изменение «private» на «protected» private означает, что никакая другая часть системы, включая производные классы, не имеет доступа к члену.

+0

** Не переустанавливайте его на защищенный. Конструктор для 'Person' инициализирует' name', а функция члена 'setName' меняет его, если это необходимо. Нет причин использовать здесь 'protected '. –

+0

Согласовано. Я просто обращался к «почему компилятор генерирует ошибку». Использование метода доступа лучше (в данном случае), чем защищено. –

2

name является частным в базовом классе, так что вы не можете получить доступ к нему из производного класса.
Предполагая, что Coach происходит публично из Person, вы можете сделать переменную-член защищенной, но, к счастью, конструктор Person принимает имя, поэтому вам не нужно напрямую обращаться к нему из производных классов. Вы можете использовать список Инициализатора, как вы делаете, и поэтому не нужно устанавливать его дважды

Coach::Coach(string name, string responsibility) 
        : Person(name){ 
       // ^^^^^^^^^^^^ 
       // Sends name to Person's constructor 
    this->responsibility = responsibility; 
} 
+0

'Coach' не нужно публиковать ** публично **; до тех пор, пока «Лицо» является базовым классом, его можно инициализировать в списке инициализаторов. –

+0

Истинно, извините, я отредактировал, я потерял следы своих мыслей – doctorlove

Смежные вопросы