Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Int a, b;






private:

// Криптографическая хэш-функция, которая будет применяься

// ко всем экземплярам класса A

HashingFunction hash_algorithm{" MD5" };

// Строка, которая представляет состояние жизненного цикла объекта

std:: string s{" Constructor run" };

};

 

Если член инициализируется в месте объявления и в списке инициализации, то выполняется только список инициализации (значения по умолчанию «затираются»). Так что предыдущий код мы можем упростить до такого:

class A {

public:

A() {}

A(int a_val): a(a_val) {}

A(D d): b(g(d)) {}

int a = 7;

int b = 5;

private:

// Криптографическая хэш-функция, которая будет применяься

// ко всем экземплярам класса A

HashingFunction hash_algorithm{" MD5" };

// Строка, которая представляет состояние жизненного цикла объекта

std:: string s{" Constructor run" };

};

 

См. также:

  • the C++ draft section " one or two words all over the place"; see proposal.
  • [N2628=08-0138] Michael Spertus and Bill Seymour: Non-static data member initializers.

 

Унаследованные конструкторы

Некоторых иногда удивляют правила областей видимости членов класса. В частности то, что члены базового класса не находится в той же области видимости, что и члены наследника:

struct B {

Void f(double);

};

struct D: B {

Void f(int);

};

B b; b.f(4.5); // Все нормально

D d; d.f(4.5); // Сюрприз: вызываем f(int) с аргументом 4

 

В С++98 мы можем «поднять» набор перегруженных функций из базового класса в наследник:

struct B {

Void f(double);

};

struct D: B {

// Добавляем все функции f() из области видимости B

// в текущую область видимости

using B:: f;

// Добавляем новую функцию с именем f()

Void f(int);

};

B b; b.f(4.5); // Все нормально

D d; d.f(4.5); // Все нормально: вызываем D:: f(double),

// которая является B:: f(double)

 

Я бы сказал, что лишь историческая случайность не позволяет этой возможности работать с конструкторами так же, как с обычными функциями. С++11 предоставляет такую возможность:

class Derived: public Base {

public:

// Поднимаем функцию f класса Base в область видимости

// класса Derived -- работает в C++98

using Base:: f;

// Добавляем новую функцию f

Void f(char);

// « Предпочитаем» использовать эту функцию f вместо Base:: f(int)

Void f(int);

// Поднимаем конструктор Base в область видимости

// класса Derived -- работает только в C++11

using Base:: Base;

Derived(char); // Добавляем новый конструктор

Derived(int); // Используем этот конструктор вместо Base:: Base(int)

//...

};

 

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

struct B1 {

B1(int) { }

};

struct D1: B1 {

using B1:: B1; // Неявно объявляет D1(int)

Int x;

};






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.