вторник, 23 ноября 2010 г.

36. Дайте определение дружественной функции. Как объявляется дружественная функция? А как определяется?

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

Объявляется и определяется точно так же как и обычная функция. Но чтобы объявить ее дружественной некоторому классу, этот класс сам должен указать у себя в объявлении этот факт ключевым словом friend

Пример:
class A{
friend void f(A& a);
int x;
};

void f(A& a){a.x = 1;}

35. Какие операции разрешается перегружать только как методы класса?

= [] () ->

воскресенье, 14 ноября 2010 г.

34. Какие операции не рекомендуется перегружать как методы класса? Почему?

Даже и не знаю. Страуструп рекомендует перегружать как методы класса только те операторы, которым требуется изменить защищенные члены. Например:
class A{
  int x;
public:
  A& operator+=(int b){x+=b;} //Этому оператор изменяет защищенный член
}

//А этому не нужно менять, и он может воспользоваться оператором +=
A operator+(A& a, int b){A res = a; return res+=b;}

33. Что означает выражение *this? В каких случаях оно используется?

Разыменованный указатель на себя. Часто используется, если функции-члену класса нужно вернуть ссылку на текущий объект:
class A{
  int x;
public:
  A& operator=(const A& a){x = a.x; return *this;} 
}

32. Как различаются перегруженная префиксная и постфиксная операции инкремента и декремента?

Выражение ++a компилятор превращает в вызов operator++(a), а для a++ в вызов operator++(a, int). Параметр int добавлен только для различия сигнатур функций и его значение не используется. Аналогично для декремента.

31. Какой результат должны возвращать операции с присваиванием?

Вообще говоря, ничего они не должны. Однако, для всех классов, по умолчанию, этот оператор означает копирование объекта и возвращение ссылки. Поэтому, при переопределении оператора, отступать от этого правила нежелательно. Но мы не обязаны использовать этот оператор только для копирования объектов.

class A{
public:
  int x;
  A& operator=(const A& a){x = a.x; return *this;} //переопределили стандартное поведение
  void operator=(int xx){x=xx;} //определили поведение при присваивании целого. Но здесь тоже можно вернуть *this.
};

int main(){
  A a;
  a=1;
  A a2;
  std::cout << (a2=a).x;
}