Форум программистов, компьютерный форум CyberForum.ru

Как инициализировать член раньше предка - C++

Восстановить пароль Регистрация
Другие темы раздела
C++ Вычислить и вывести на экран в виде таблицы значения функции http://www.cyberforum.ru/cpp-beginners/thread427003.html
Не пойму гдето ошибка, не хочет считать по второй формуле помогите пожалуйста... условия: Вычислить и вывести на экран в виде таблицы значения функции F в интервале Xнач до Xкон c шагом dX. ax^2+bx+c при a<0 и c!=0 F= -a/x-c при a>0 и c=0 a(x+c) в остальных случаях где а,b,c - действительные числа Значения a, b ,c ,Xнач, Xкон, dX ввести с клавиатуры
C++ в каком направлении действовать при написании программы дано задание: "Проверить, является ли выражение, состоящее только из прописных букв заданной строки, палиндромом. Если да, то напечатать полученный палиндром. В противном случае вывести строку, состоящую из символов исходной строки с удаленными прописными символами." подскажите пожалуйста, с чего начать программу хоть что-нибудь подскажите, буду очень благодарна http://www.cyberforum.ru/cpp-beginners/thread427001.html
Вычисление интеграла C++
задача такая Вычислить с точностью\varepsilon интеграл ,где y=f(x) - прямая проходящая через точки A(c,d) и B - точку минимума \int_{a}^{b}\sin (f1^2(x))dx F(t)=5{e}^{-t}+4t-\frac{t^3}{3} - определенную на отрезке , с точностью \varepsilon исходные данные
Сумма ряда. Число повторений цикла. Нужна проверка и помощь C++
Текст задания находится во вложении. Сумма ряда и выражение для проверки не сходятся, хотя сделано по аналогичному примеру. Не могу разобраться в чем ошибка. Помогите пожалуйста) #include<stdio.h> #include<conio.h> #include<math.h> #define e 0.00001 int main() {
C++ Поиск позиции символа в строке http://www.cyberforum.ru/cpp-beginners/thread426976.html
Здравствуйте, у меня есть строка со словом и строка с прочерками (--------), длина у них одинаковая, есть кнопки, на которых буквы алфавита. Мне нужно, чтоб при нажатии на любую из кнопок проверялась строка со словом на наличие символа (буквы алфавита) и если символ присутствует в строке со словом, то в строку с прочерками вставить этот символ на ту позицию, в которой он (символ) находится в...
C++ Задача на массив символьных строк. Возможно я не первый кто просит помочь в данной задачи, но все же повторюсь.: Дан текст, состоящий из n предложений. Предложение представляет собой арифметическое выражение. Создать массив, включающий в себя идентификаторы из всех предложений. подробнее

Показать сообщение отдельно
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
12.01.2012, 19:30     Как инициализировать член раньше предка
Изредка, но может встретиться в жизни такая ситуация, когда надо инициализировать один из членов класса раньше предка. Обычно в том случае, если при инициализации предок ссылается на данные этого члена. Приведу пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Foundation { // Фундамент
public:
    Foundation(float Width, float Height);  // Выкопать яму нужных размеров и залить бетоном
private:
    // Нельзя копировать и присваивать
    Foundation(const Foundation&);
    Foundation& operator = (const Foundation&);
};
 
class FloorPlan {  // Чертежи дома
public:
    FloorPlan(const string& name);  // По названию модели дома
    FloorPlan(const FloorPlan&);    // Копировать в принципе можно, но дорого...
    float Width() const;    // Ширина и высота основания
    float Height() const;
private:
    FloorPlan& operator = (const FloorPlan&);
};
 
class Floor { // Этаж
// ...
};
 
class Building: public Foundation { // Здание
private:
    FloorPlan plan;
    vector<Floor> floors;
public:
    Building(const string& name): Foundation(plan.Width(), plan.Height()), plan(name) {ConstructFloors();} // УПС!
    static void ConstructFloors(vector<Floor>& floors, const FloorPlan& plan);
private:
    // Нельзя копировать и присваивать
    Building(const Building&);
    Building& operator = (const Building&);
};
Класс Building наследует от Foundation и содержит чертёж как член. Для создания фундамента надо знать размеры, которые может предоставить чертёж. Но вот досада-то: фундамент является предком и инициализируется раньше всех членов. Так что мы не можем использовать ещё не инициализированный plan, чтобы узнать размеры Foundation. Как быть? Во-первых, можно наследовать Building от FloorPlan и Foundation:
C++
1
2
3
4
5
6
class Building: private FloorPlan, public Foundation {
private:
    vector<Floor> floors;
public:
    Building(const string& name): FloorPlan(name), Foundation(Width(), Height()) {ConstructFloors(floors, *this);}
};
Недостатки метода очевидны: мало того, что мы нарушаем идеологическую чистоту, мы ещё и заливаем в Building интерфейс FloorPlan, что может привести к замусориванию и неожиданным последствиям.

Второй подход проще и очевиднее: надо сначала создать отдельный объект FloorPlan, использовать его для создания Foundation и перекинуть в Building:
C++
1
2
3
4
5
6
7
8
class Building: public Foundation {
private:
    FloorPlan plan;
    vector<Floor> floors;
public:
    Building(const FloorPlan &p): Foundation(p.Width(), p.Height()), plan(p) {ConstructFloors(floors, plan);}
    // Теперь вместо Building d("дача"); надо писать Building d(FloorPlan("дача"));
};
Плохо то, что приходится копировать FloorPlan: это может быть дорогостоящая операция (очереди в мэрии за разрешениями, взятки клеркам, медленный ксерокс). Можно передавать не сам FloorPlan, а указатель на динамически создаваемый объект с передачей владения. Возможности нового стандарта C++11, уже реализованные в последних версиях компиляторов Visual Studio 2010 и GCC позволяет максимально чётко выразить передачу владения и защититься от неприятных последствий при помощи unique_ptr:
C++
1
2
3
4
5
6
7
8
9
class Building: public Foundation {
private:
    std::unique_ptr<const FloorPlan> pplan; // Автоматически уничтожается при уничтожении Building.
    vector<Floor> floors;
public:
    Building(std::unique_ptr<const FloorPlan> p): Foundation(p->Width(), p->Height()), pplan(std::move(p)) {ConstructFloors(floors, *pplan);}
    // Теперь конструирование выглядит ещё веселее:
    // Building d(std::unique_ptr<FloorPlan>(new FloorPlan("дача")));
};
Теперь мы избавились от затратного копирования чертежей, однако неужели нельзя сделать лучше? Разумеется, можно. Тот же unique_ptr основывается на концепции уникального объекта, содержимое которого нельзя копировать, но можно перемещать. Так почему бы не сделать FloorPlan перемещаемым?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class FloorPlan {
public:
    FloorPlan(const string& name); 
    FloorPlan(FloorPlan&& source);  // Перекидываем всё содержимое в this и помечаем source как "пустой"
    float Width() const;
    float Height() const;
};
 
class Building: public Foundation {
private:
    FloorPlan plan;
    vector<Floor> floors;
public:
    Building(FloorPlan &&p): Foundation(p.Width(), p.Height()), plan(std::move(p)) {ConstructFloors(floors, plan);}
    // Мы снова вернулись к Building d(FloorPlan("дача"));
};
Но и этого мало! Здания должны конструироваться с удобством! И при помощи другой особенности С++11, делегации конструкторов, мы можем это сделать:
C++
1
2
3
4
5
6
7
8
9
10
11
class Building: public Foundation {
private:
    FloorPlan plan;
    vector<Floor> floors;
    // Теперь мы спрячем этот конструктор от народа
    Building(FloorPlan &&p): Foundation(p.Width(), p.Height()), plan(p) {ConstructFloors(floors, plan);}
public:
    Building(const string& name): Building(FloorPlan(name)) {} // Просто создаём временный объект FloorPlan и перекидываем создание скрытому конструктору
    // Мы снова вернулись к старому доброму Building d("дача");
private:
};
Добавлю ложку дёгтя в бочку мёда: Visual Studio 2010 делегировать конструкторы не умеет. Поиграться таким фокусом можно пока только в GCC начиная с версии 4.7.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
Текущее время: 23:34. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru