Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Либерти Джесс. Освой самостоятельно С++ за 21 день. - royallib.ru.rtf
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
2.55 Mб
Скачать

Передача объекта как значения

В листинге 15.3 показано, как создание одного объекта Employee приводит к вызову пяти конструкторов класса String. Листинг 15.4 — это еще один переписанный вариант программы. В нем нет дополнительных операторов вывода помимо представленных в листинге 15.1 (сейчас они разблокированы) и используется статическая переменная-член ConstructorCount, объявленная в классе String.

Как следует из объявления в листинге 15.1, значение переменной ConstructorCount увеличивается на единицу при каждом вызове конструктора класса String. В конце программы, представленной в листинге 15.4, объект Employee передается на печать сначала как ссылка, а затем как значение. Статическая переменная-член ConstructorCount отслеживает, сколько объектов класса String создается при разных способах передачи объекта Employee как параметра функции.

Примечание: Перед компиляцией этого листинга в программе листинга 15.1 дополнительно к тем строкам, которые были разблокированы для листинга 15.3, следует снять символы комментариев со строк 23, 39, 52, 64, 76 и 153.

Листинг 15.4. Передача объекта как значения

1: #include "String.hpp"

2:

3: class Employee

4: {

5:

6:    public:

7:       Employee();

8:       Employee(char *, char *, char *, long);

9:       ~Employee();

10:      Employee(const Employee&);

11:      Employee & operator= (const Employee &);

12:

13:      const String & GetFirstName() const

14:         { return itsFirstName; }

15:      const String & GetLastName() const { return itsLastName; }

16:      const String & GetAddress() const { return itsAddress;

17:      long GetSalary() const { return itsSalary; }

18:

19:      void SetFirstName(const String & fName)

20:         { itsFirstName = fName; }

21:      void SetLastName(const String & lName)

22:         { itsLastName = lName; }

23:      void SetAddress(const String & address)

24:         { itsAddress = address; }

25:      void SetSalary(long salary) { itsSalary = salary; }

26:   private:

27:      String itsFirstName;

28:      String itsLastName;

29:      String itsAddress;

30:      long itsSalary;

31: };

32:

33: Employee::Employee();

34:    itsFirstName(""),

35:    itsLastName(""),

36:    itsAddress(""),

37:    itsSalary(0)

38: { }

39:

40: Employee::Employee(char * firstName, char * lastName,

41:    char * address, long salary):

42:    itsFirstName(firstName),

43:    itsLastName(lastName),

44:    itsAddress(address),

45:    itsSalary(salary)

46: { }

47:

48: Employee::Employee(const Employee & rhs):

49:    itsFirstName(rhs.GetFi rstName()),

50:    itsLastName(rhs.GetLastName()),

51:    itsAddress(rhs.GetAddress()),

52:    itsSalary(rhs.GetSalary())

53: { }

54:

55: Employee::~Employee() { }

56:

57: Employee & Employee::operator= (const Employee & rhs)

58: {

59:    if (this == &rhs)

60:       return *this;

61:

62:    itsFirstName = rhs.GetFirstName();

63:    itsLastName = rhs.GetLastName();

64:    itsAddress = rhs.GetAddress();

65:    itsSalary = rhs.GetSalary();

66:

67:    return *this;

68: }

69:

70: void PrintFunc(Employee);

71: void rPrintFuno(const Employee&):

72:

73: int main()

74: {

75:    Employee Edie("Jane","Doe","1461 Shore Parkway", 20000);

76:    Edie.SetSalary(20000);

77:    Edie.SetFirstName("Edythe");

78:    String LastName("Levine");

79:    Edie.SetLastName(LastName); 80:

81:    cout << "Constructor count: " ;

82:    cout << String;:ConstruotorCount << endl;

83:    rPrintFunc(Edie);

84:    cout << "Constructor count: ";

85:    cout << String::ConstructorCount << endl;

86:    PrintFunc(Edie);

87:    cout << "Constructor count: ";

88:    cout << String::ConstructorCount << endl;

89:    return 0;

90: }

91: void PrintFunc (Employee Edie)

92: {

93:

94:    cout << "Name: ";

95:    cout << Edie.GetFirstName().GetString();

96:    cout << " " << Edie.GetLastName().GetString();

97:    cout << ".\nAddress: ";

98:    cout << Edie.GetAddress().GetString();

99:    cout << ".\nSalary: " ;

100:   cout << Edie.GetSalary();

101:   cout << endl;

102:

103: }

104:

105: void rPrintFunc (const Employee& Edie)

106: {

107:    cout << "Name: ";

108:    cout << Edie.GetFirstName().GetString();

109:    cout << " " << Edie.GetLastName().GetString();

110:    cout << "\nAddress: ";

111:    cout << Edie.GetAddress().GetString();

112:    cout << "\nSalary: " ;

113:    cout << Edie.GetSalary();

114:    cout << endl;

115: }

Результат:

String(char*) constructor

   String(char*) constructor

   String(char*) constructor

   String(char*) constructor

   String destructor

   String(char*) constructor

Constructor count: 5

Name: Edythe Levine

Address: 1461 Shore Parkway

Salary: 20000

Constructor count; 5

   String(String&) constructor

   String(String&) constructor

   String(String&) constructor

Name: Edythe Levine

Address: 1461 Shore Parkway

Salary: 20000

   String destructor

   String destructor

   String destructor

Constructor count: 8

String destructor

   String destructor

   String destructor

   String destructor

Анализ: Как видно по данным, выводимым программой, в процессе создания одного объекта Employee создается пять объектов класса String. Когда объект Employee передается в функцию rPrintFunc() как ссылка, дополнительные объекты Employee не создаются. Соответственно не создаются и дополнительные объекты String. (Все они, кстати, также автоматически передаются как ссылки.)

Когда объект Employee передается в функцию PrintFunc() как значение, создается копия объекта Employee вместе с тремя объектами класса String (для этого используется конструктор-копировщик).