При обращении к inline-методу идет обращение к полю. Метод д.б. перенесен в h-файл. Иначе компилятор будет делать вызов метода. На этапе компоновки получим ошибку линкера «нет метода».



Мы поможем в написании ваших работ!


Мы поможем в написании ваших работ!



Мы поможем в написании ваших работ!


ЗНАЕТЕ ЛИ ВЫ?

При обращении к inline-методу идет обращение к полю. Метод д.б. перенесен в h-файл. Иначе компилятор будет делать вызов метода. На этапе компоновки получим ошибку линкера «нет метода».



 

 

В С++ объекты могут агрегироваться по ссылке и по значению (агрегирование по ссылке похоже на агрегирование в Delphi).

 

Агрегирование по значению:

 

class TDelimitedReader

{

public:

...

private:

std::string m_FileName;

};

 

Агрегированные по значению объекты конструируются автоматически в порядке объявления после вызова конструктора базового класса (если не указан другой способ инициализации).

Стандартный способ инициализации можно переопределить до открывающей фигурной

скобки конструктора:

TTextReader::TDelimitedReader() : TTextReader(), m_FileName("c:/myfile.txt")

{

...

}

Следует отметить, что данная запись отличается от следующей записи:

 

TDelimitedReader::TDelimitedReader() : TTextReader()

{

m_FileName = "c:/myfile.txt";

}

Во втором случае строка вначале создается пустой, а в теле конструктора переприсваивается.

 

Объекты, агрегированные по ссылке, нужно создавать вручную с помощью оператора new, а удалять – с помощью оператора delete:

 

class TDelimitedReader : publicTTextReader

{

...

private:

std::string m_FileName;

TItems *m_Items;

};

TDelimitedReader::TDelimitedReader() : TTextReader(), m_FileName("c:/myfile.txt")

{

m_Items = new TItems;

}

TDelimitedReader::~TDelimitedReader()

{

delete m_Items;

}

 

Правило конструирования агрегированных объектов:

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

ƒ объекты, агрегированные по ссылке, инициализируются в теле конструктора.

 

Агрегация – размещение данных в виде полей внутри других данных.

Наследование

Наследование класса выполняется следующим образом:

 

сlass TDelimitedReader: public TTextReader

{

...

};

 

При наследовании указываются атрибуты доступа к элементам базового класса (public, protected, private). Для того чтобы понять смысл атрибута доступа к базовому классу, базовый класс следует рассматривать, как поле производного класса.

 

Private-наследование: в производном классе не видно то, что в базовом классе объявлено как private.

Protected-наследование: в производном классе видим public & protected.

Конструкторы и деструкторы

 

Конструктор создает объект и инициализирует память для него (деструктор – наоборот).

 

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

 

class TTextReader

{

public:

TTextReader();

~TTextReader();

};

 

В Delphi стандартный деструктор является виртуальным. В С++ это определяет программист, если планируется создавать объекты в динамической памяти (по ссылке), деструктор необходимо делать виртуальным:

virtual ~TTextReader();

Без virtual деструктор вызовется правильно, только если объект создан на стеке.

У деструкторов обычно нет параметров. Деструктор м.б. только один.

 

Стандартные конструкторы

 

Если программист не определяет в классе конструкторы, то компилятор создает автоматически два конструктора:

ƒ конструктор без параметров

ƒ конструктор копирования

 

class TTextReader

{

public:

TTextReader(); // конструктор без параметров

TTextReader(const TTextReader &R); // конструктор копирования

}

 

Если программист определил хотя бы один конструктор в класс – компилятор не создаст никаких стандартных конструкторов.

 

Конструктор без параметров создается для того, чтобы можно было написать:

TTextReader R;

 

Конструктор копирования нужен для следующей записи:

TTextReader R1 = R2; // означает TTextReader.R1(R2);

 

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

 

Следует отметить, что запись:

TTextReader R1 = R2;

 

и два оператора:

TTextReader R1;

R1 = R2;

 

имеют схожий синтаксис с вызовом конструктора копирования, но разную семантику: в первом случае объект создается конструктором копирования, во втором – конструктором без параметров, а затем с помощью оператора‘=’ выполняется присваивание одного объекта другому (данный вариант требует перегрузки оператора‘=’ для класса TTextReader).

 

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

 

Вы можете использовать конструктор более чем только для инициализации нового объекта. Например, наша программа содержит такой оператор в функции main():

 

stockl = Stock (" Nifty Foods ", 10, 50 .0 ) ;

 

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

 

 

Объекты с автоматическим хранением удаляются в порядке, обратном тому, в котором они создавались.

 

Предположим, что вы создали нечто наподобие:

 

 

class Dwelling

{

public:

virtual void showperks (int а) const;

} ;

class Hovel: publiv Dwelling

{

public:

virtual void showperks () const;

} ;

 

 

Hovel trurnp;

trurnp.showperks() ; // верно

trurnp.showperks(S) ; // неверно

 

Если вы переопределяете унаследованный метод, необходимо убедиться в точном совпадении с исходным прототипом. Одно сравнительно новое исключение из этого правила состоит в том, что возвращаемый тип (указатель или ссылка на базовый класс) может быть заменен указателем или ссылкой на производный класс. Это свойство называеется изменчивостъю возвращаемого типа, поскольку возвращаемый тип допускается изменять параллельно с типом класса.

 

Если объявление класса перегружается, вам необходимо переопределить все версии базового класса в производнам классе. Если вы переопределяете только одну версию, то остальные становятся скрытыми и не могут использоваться объектами производного класса. Если не нужны никакие изменения, то переопределение может просто вызывать версию базового класса.

 



Последнее изменение этой страницы: 2016-08-14; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 34.239.179.228 (0.007 с.)