Выбрать главу

31: }

32:

33: void myClass::ShowMember()

34: {

35:    cout << "itsMember: " << itsMember << endl;

36: }

37:

38: void myCIass:: ShowSecond()

39: {

40:    cout << "itsSecond: " << itsSecond << endl;

41: }

42:

43: void myClass::ShowThird()

44: {

45:    cout << "itsThird: " << itsThird << endl;

46: }

47: int myClass::itsStatic = 0;

48:

49: int myClass::GetStatic()

50: {

51:    return itsStatic;

52: }

53:

54: int main()

55: {

56:    void (myClass::*PMF) ();

57:

58:    myClass obj1;

59:    PMF=myClass::ShowMember;

60:    (obj1.*PMF)();

61:    PMF=myClass::ShowSecond;

62:    (obj1.*PMF)();

63:    PMF=myClass::ShowThird;

64:    (ob]1 "PMF)();

65:    cout << "Static: " << myClass::GetStatic() << endl;

66:

67:    myClass obj2;

68:    PMF=myClass::ShowMerober;

69:    (obj2.*PMF)();

70:    PMF=myClass::ShowSecond;

71:    (obj2.*PMF)();

72:    PMF=myClass::ShowThird;

73:    (obj2. *PMF)();

74:    cout << "Static: " << myClass::GetStatic() << endl;

75:

76:    myClass obj3;

77:    PMF=myClass::ShowMember;

78:    (obj3. *PMF)();

79:    PMF=myClass::ShowSecond;

80:    (obj3.*PMF)();

81:    PMF=royClass::ShowThird;

82:    (obj3.*PMF)();

83:    cout << "Static: " << myClass::GetStatic() << endl;

84:    return 0;

85: }

День 15

 Контрольные вопросы

1. Как объявить класс, являющийся частным проявлением другого класса?

С помощью открытого наследования.

2. Как объявить класс, объекты которого должны использоваться в качестве переменных-членов другого класса?

Необходимо использовать вложение классов.

3. В чем состоят различия между вложением и делегированием?

Под вложением понимают использование объектов одного класса в качестве переменных-членов другого класса. Под делегированием — передачу одним классом другому классу выполнения некоторых специфических функций. В то же время делегирование часто реализуется за счет вложения классов.

4. В чем состоят различия между делегированием и выполнением класса в пределах другого класса?

Под делегированием понимают передачу одним классом другому классу выполнения некоторых специфических функций. Под реализацией в пределах другого класса — наследование выполнения специфических функций от другого класса.

5. Что такое функция-друг?

Это функция, объявленная с целью получения доступа к защищенным и закрытым членам другого класса.

6. Что такое класс-друг?

Зто класс, объявленный таким образом, чтобы все его функции-члены были дружественными по отношению к другому классу.

7. Если класс Dog является другом Boy, то можно ли сказать, что Boy — друг Dog?

Нет, дружественность классов не взаимна.

8. Если класс Dog является другом Boy, а Terrier произведен от Dog, является ли Terrier другом Boy?

Нет, дружественность классов не наследуется.

9. Если класс Dog является другом Boy, а Boy — другом House, можно ли считать Dog другом House?

Нет, дружественность классов не ассоциативна.

10. Где необходимо размешать объявление функции-друга?

В любом месте внутри объявления класса. Не имеет никакого значения, в каком именно разделе будет помешено это объявление — в public:, protected: или private:.

 Упражнения

 1. Объявите класс Animal (Животное), который содержит переменную-член, являющуюся объектом класса String.

class Animaclass="underline"

{

   private:

      String itsName;

};

2. Опишите класс BoundedArray, являющийся массивом.

class boundedArray : public Array

{

   // ...

}

3. Опишите класс Set, выполняемый в пределах массива BoundedArray.

class Set : private Array

{

   // ...

}

4. Измените листинг 15.1 таким образом, чтобы класс String включал перегруженный

оператор вывода (>>).

1: #include <iostream.h>

2: #include <string.h>

3:

4: class String

5: {

6:    public:

7:       // конструкторы

8:       String();

9:       String(const char *const):

10:      String(const String &);

11:      ~String();

12:

13:      // перегруженные операторы

14:      char & operator[](int offset);

15:      char operator[](int offset) const:

16:      String operator+(const String&);

17:      void operator+=(const String&);

18:      String & operator= (const String &);

19:      friend ostream& operator<<

20:         ( ostream& _theStream,String& theString);

21:      friend ist.ream& operator>>

22:         ( istream& _theStream,String& theString);

23:      // Общие функции доступа

24:      int GetLen()const { return itsLen; }

25:      const char * GetString() const { return itsString; }

26:      // static int ConstructorCount:

27:

28:   private:

29:      String (int); // закрытый конструктор

30:      char * itsString;

31:      unsigned short itslen;

32:

33: };

34:

35: ostream& operator<<( ostream& theStream,String& theStnng)

36: {

37:    theStream << theString.GetString();

38:    return theStream;

39: }

40:

41: istream& operator>>( istream& theStream,String& theString)

42: {

43:    theStream >> theString.GetString();

44:    return theStream;

45: }

46:

47: int main()

48: {

49: StringtheString("npHBeT, мир.");

50: cout << theString;

51:     return 0;

52: }

5. Жучки: что неправильно в этой программе?

1: #include <iostrearm.h>

2:

3: class Animal;

4:

5: void setValue(Animal& , int);

6:

7:

8: class Animal

9: {

10:   public:

11:      int GetWeight()const { return itsWeight; }

12:      int GetAge() const { return itsAge; }

13:   private:

14:      int itsWeight;

15:      int itsAge;

16: };

17:

18: void setValue(Animal& theAnimal, int theWeight)

19: {

20:    friend class Animal;

21:    theAnimalitsWeight = theWeight;

22: }

23:

24: int main()

25: {

26:    Animal peppy;

27:    setValue(peppy,5):

28:    return 0;

29: }

Нельзя помещать объявление friend в функцию. Нужно объявить функцию другом в объявлении класса.

6. Исправьте листинг, приведенный в упражнении 5, и откомпилируйте его.

1: #include <iostream.h>

2:

3: class Animal;

4:

5: void setValue(Animal& , int);

6:

7:

8:  class Animal

9:  {

10:    public:

11:       friend void setValue(Animal&, int);

12:       int GetWeight()const { return itsWeight; }

13:       int GetAge() const { return itsAge; }

14:    private:

15:       int itsWeight;

16:       int itsAge;

17: };

18:

19: void setValue(Animal& theAnimal, int theWeight)

20: {

21:    theAnimal.itsWeight = theWeight;

22: }

23:

24: int main()

25: {

26:    Animal peppy;

27:    setValue(peppy,5);

28:    return 0;

29: }

7. Жучки: что неправильно в этой программе?

1: #include <iostream.h>

2:

3: class Animal;

4:

5: void setValue(Animal& , int):

6: void setValue(Animal& , int.int);

7:

8: class Animal

9: {

10:   friend void setValue(Animal& ,int):

11:   private:

12:      mt itsWeight;

13:      int itsAge;

14: };

15:

16: void setValue(Animal& theAnimal, int theWeight)

17: {

18:    theAnimal.itsWeight = theWeight;

19: }

20:

21:

22: void setValue(Animal& theAnimal, int theWeight, int theAge)

23: {

24:    theAnimal.itsWeight = theWeight:

25:    theAnimal.itsAge = theAge;

26: }

27:

28: int main()

29: {

30:    Animal peppy;

31:    setValue(peppy,5);

32:    setValue(peppy,7,9);

33:    return 0:

34: }

Функиия setValue(Animal& ,int) была объявлена дружественной, но перегруженная

функция setValue(Animal& ,int,int) не была объявленадружественной.

8. Исправьте листинг, приведенный в упражнении 7, и откомпилируйте его.

1: #include <iostream.h>

2:

3: class Animal;

4:

5: void setValue(Animal& , int);

6: void setValue(Animal& , int.int);

7:

8: class Animal

9: {

10:   friend void setValue(Animal& ,int);

11:   friend void setValue(Animal& ,int.int): // изменение!

12:   private:

13:      int itsWeight;

14:      int itsAge;

15: };

16:

17: void setValue(Animal& theAnimal, int theWeight)

18: {

19:    theAnimal.itsWeight = theWeight;

20: }

21:

22:

23: void setValue(Animal& theAnimal, int theWeight, int theAge)

24: {

25:    theAnimal.itsWeight = theWeight;

26:    theAnimal.itsAge = theAge;

27: }

28:

29: int main()

30: {

31:    Animal peppy;

32:    setValue(peppy.5);

33:    setValue(peppy,7,9);

34:    return 0;

35: }