Правила программирования на Си и Си++



         

110. Никогда не допускайте открытого доступа к закрытым данным - часть 3


63 {

64    return strcmp(buf, r.buf) > 0;

65 }

66 //------------------------------------------------–––––––––––-----

67 /* виртуальный */ int string::operator==( const

string &r ) const

68 {

69    return strcmp(buf, r.buf) == 0;

70 }

71 //--------------------------------------------------–––––––––––---

72 /* виртуальный */ void string::print( ostream &output ) const

73 {

74    cout << buf;

75 }

76 //–------------------------------------------------–––––––––––----

77 inline ostream &operator<<( ostream &output, const string &s )

78 {

79 // Эта функция не является функцией-членом класса string,

80 // но не должна быть дружественной, потому что мной тут

81 // реализован метод вывода строкой своего значения.

82

83    s.print(output);

84    return output;

85 }

Вы заметите, что я умышленно не реализовал следующую функцию в листинге 7:

string::operator const

char*() { return buf; }

Если бы реализовал, то мог бы сделать следующее:

void f( void

)

{

   string s;

   // ...

   printf("%s\n", (const char*)s );

}

но я не cмогу реализовать функцию operator

char*(), которая бы работала со строкой Unicode, использующей для символа 16-бит. Я должен бы был написать функцию operator

wchar_t*(), тем самым модифицировав код в функции f():

printf("%s/n", (const wchar_t*)s );

Тем не менее, одним из главных случаев, которых я стараюсь избежать при помощи объектно-ориентированного подхода, является необходимость модификации пользователя объекта при изменении внутреннего определения этого объекта, поэтому преобразование в char*

неприемлемо.

Также есть проблемы со стороны внутренней согласованности. Имея указатель на buf,

возвращенный функцией operator

const char*(), вы все же можете модифицировать строку при помощи указателя и испортить поле length, хотя для этого вам придется немного постараться:

string s;

// ...

char *p = (char *)(const char *)s;

gets( p );

В равной степени серьезная, но труднее обнаруживаемая проблема возникает в следующем коде:




Содержание  Назад  Вперед