Академический Документы
Профессиональный Документы
Культура Документы
- b) Если есть ошибки в реализации методов заданных классов и функции main (),
исправьте их, используя операцию разрешения области видимости «::».
Какие конструкторы и деструкторы и в каком порядке будут вызываться при работе данной программы?
Отлично, есть кое где замечания -Фалько Ник.Серг. -желтым цветом
#include <iostream>
using namespace std;
int main () {
B a; // создаем экземпляр "a" класса B Конструкторы : A() , B() важен порядок
class C { // Объявляем класс C , который содержит объект "b" типа B , и объект "a" , типа A
B b;
A a;
public:// порядок иниц Прата стр 737 попробуйте записать в обратном порядке C{ A a;B b; public :…..
C(): b(), Конструкторы : A() , B() важен порядок a (b) A ( const A & ) важно ктор копирования
для А но передается УЖЕ созданный В b . И только в конце C() { } // для объекта b - будет вызван ctor
по умолчанию. А для объекта a - будет вызван ctor , копирования
};
C c; // создаем экземпляр "с" класса С
x = a.A::f (); // 3) Ошибка - Тут нужно явно указать область видимости A::f() . Так как
компилятор для объекта "a", типа "B" - будет пытаться найти функцию B::f() , но у него не получиться
это сделать , поэтому он будет пытаться взывать функции B::f(int) и B::f(int , int) , но не сможет из-
за не хватки передаваемых параметров
x = a.f (7); // Тут мы можем явно не указывать область видимости функции , так как в любом
случае будет вызван метод B::f(int)
return a.g (& a, & a); // И тут тоже необязательно явно указывать область видимости B:: . Кроме того
формальный параметр "A *pa" - может принимать ссылку на объект "a" , типа B . Так как класс A -
родитель класса B
}
4.2. Есть ли ошибки в приведенном фрагменте программы? Если есть, то объясните, в чем они
заключаются.
Ошибочные конструкции вычеркнуть из текста программы. Что будет выдано в стандартный канал вывода
при работе программы?
#include <iostream>
using namespace std;
public:
virtual int g (double x) { // виртуальная функция g - принимающая формальный параметр double x
h (); // вызов функции X::h()
cout << "X::g" << endl; // вывод на экран
return 1; // возвращаем значение 1
}
void h () { t (); cout << "X::h" << endl;} // функция h , которая вызывает виртуальную функцию t()
virtual void t () { cout << "X::t" << endl;} // виртуальная функция t ()
};
int main() {
X a; // создаём объект "a" класса X
Z b; // создаём объект "b" класса Z
X * p = &b; // указатель базового класса X - ссылается на объект b , класса Z ( наследника )
p -> g(1.5); // косвенный вызов функции g - будет вызвана функция , Z::g( double ) ( динамическое
связывание )
p -> h(); // Вызов функции X::h() ( Почему не Z::h() ? )Потому что НЕТ virtual в БАЗЕ и h не вирт
// Здесь override
//p -> t(5); // Ошибка - Функция X::t() - не может быть вызвана , так как мы передаем параметр 5 .
Компилятор попытается вызвать виртуальную ОШИБКА функцию X::t()
// но не сможет этого сделать , так как количество передаваемых параметров , больше чем количество
ожидаемых
}
Вывод на экран :
// Z::t
// Z::h
// Z::g
// X::t
// X::h
3.2. - с) Если есть ошибки в реализации методов заданных классов и функции main (),
исправьте их, используя операцию разрешения области видимости «::».
Какие конструкторы и деструкторы и в каком порядке будут вызываться при работе данной программы?
#include <iostream>
using namespace std;
void C::g() {
x = A::f (); // 1) Ошибка - тут надо явно указать область видимости A::f() . Так как
компилятор попытается взывать функцию C::f(int) , но не сможет этого сделать из-за отсутствия
передаваемого параметра
f (3); // тут вызовется метод C::(int)
x = ::f (4, 5); // 2) Ошибка - в этой строке тоже необходимо указать области видимости " ::f "
, чтобы вызвалась функция ::f(int a , int b ) . Иначе компилятор попытается вызвать функцию С::f(int) -
но у него не получиться это сделать из-за того , что функция ожидает 1 параметр , а мы передаем ей - 2
x = 6; // поле x - инициализируется значением 6
}
int main () {
C c; // создаем объект "c" , класса C
B b; // создаем объект "b" , класса B
A a; // создаем объект "a" , класса A
c.A::f(); // 3) Ошибка - чтобы вызвался метод A::f() - нужно явно указать его область видимости , то
есть - A:: . Иначе компилятор снова попытается вызвать C::f(int)
c.f(7); // вызываем метод C::f()
x = f('8', 9); // Вызывается глобальная функция f::(int , int ) . А фактический параметр (char) -
'8' , приводиться к int , с помощью таблицы ASCII . Таким образом (char) '8' = (int) 56
return -1;
}
//Порядок вызова конструкторов - A() , B() , C() , B() , A() Важен порядок class C: public A,
public B
//Порядок вызова деструкторов - ~A() , ~B() , ~C() , ~B() , ~A() Автоматом обратно кторам
3.4. Если есть ошибки в следующем фрагменте, то в чем они заключаются ?
//Исправьте ошибки, ничего не удаляя, добавив в общей сложности не более 12 символов.
#include <iostream>
using namespace std;
class T: public S { // объявление класса T , который " приватно " наследуется от класса S
public:
int t; // public поле t
void tp(int ti) { t = ti; s = ti; } // функция tp , которая инициализирует поля "t" и "s" -
значениями параметра ti.
// Не смотря на то , что класс S - наследуется приватно . Мы можем получить доступ к переменной
S::s - так как при private наследовании :
// Protected и public члены базового класса S - становятся private в дочернем классе T.
};
class U: public T { // объявление класса U , который " приватно " наследуется от класса T
public:
int u; // поле u
void up(int ui) { u = ui; t = ui; s = ui; } // функция up , которая инициализирует поля "u" ,
"t" и "s" - значениями параметра ui .
// 1) Тут возникнет ошибочка , так как благодаря private наследованию - переменная S::s -
изменила свой модификатор доступа на private в классе T , который " приватно " наследуется от класса S
};