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

Как это сделать? - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 5.00
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
19.04.2013, 20:14     Как это сделать? #1
Класс, у него несколько гарантированных экземпляров, из них ровно один создан конструктором по умолчанию, средствами языка запрещено создавать другие экземпляры конструктором по умолчанию, но можно создавать дополнительные экземпляры конструкторами с параметрами, любой экземпляр может быть приведён к std::string, или без приведения выведен в поток std::cout, все поля private, единственный public конструктор принимает два дабла, std::string и ссылку на собственный класс, которая в том числе может ссылаться на экземпляр, созданный конструктором по умолчанию.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.04.2013, 20:14     Как это сделать?
Посмотрите здесь:

Как это сделать? C++
Ну как это сделать? C++
C++ Как это сделать?
C++ Как это сделать ? [c++]
Как это сделать? C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
21.04.2013, 11:35  [ТС]     Как это сделать? #21
Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
unique_ptr автоматически прибьёт объект, за которым он следит, как только ему самому придёт время умирать. Неявно. Он умрёт тогда же, когда и любой другой глобальный объект — при выходе из main. (Опять же, если оставить в стороне dll.)
Допустим. А момент создания? Обычные глобальные объекты создаются неявно на входе в main.

Добавлено через 5 минут
Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
Вы путаете понятия переменной и объекта. Объекты есть в памяти во время выполнения программы. Переменные — это идентификаторы для компилятора, эти самые имена; в Си++ их объективно нет во время выполнения программы.
Я ничего не путаю, а если уж говорить о низком уровне, то объектов тоже нет во время исполнения, а есть только их скалярные челны-переменные и члены-функции. На высоком же уровне переменная есть ячейка памяти для хранения изменяемых данных, эта ячейка может иметь известное компилятору имя, прописанное в исходном тексте программы и заносимое оттуда на этапе компиляции в таблицу переменных. Так что объекты отличаются от остальных переменных ровно двумя аспектами:
1. Они не скалярны.
2. С ними связан код.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
21.04.2013, 12:33     Как это сделать? #22
Цитата Сообщение от taras atavin Посмотреть сообщение
Допустим. А момент создания? Обычные глобальные объекты создаются неявно на входе в main.
Обычные глобальные объекты инициализируются чёрти когда. Особенно это касается объектов, определяемых в различных единицах трансляции, которые используют друг друга. Немного цитаток:
Definitions of explicitly specialized class template static data members have ordered initialization. Other class template static data members (i.e., implicitly or explicitly instantiated specializations) have unordered initialization.

Otherwise, the initialization of a variable is indeterminately sequenced with respect to the initialization of a variable defined in a different translation unit.

Otherwise, the unordered initialization of a variable is indeterminately sequenced with respect to every other dynamic initialization.

As a consequence, if the initialization of an object obj1 refers to an object obj2 of namespace scope potentially requiring dynamic initialization and defined later in the same translation unit, it is unspecified whether the value of obj2 used will be the value of the fully initialized obj2 (because obj2 was statically initialized) or will be the value of obj2 merely zero-initialized.

It is implementation-defined whether the dynamic initialization of a non-local variable with static storage duration is done before the first statement of main.

It is implementation-defined whether the dynamic initialization of a non-local variable with static or thread storage duration is done before the first statement of the initial function of the thread.
Отдельная функция позволяет инициализировать всё в чётко определённый момент и в чётко определённом порядке, прописанном в этой функции. В отличие от.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
21.04.2013, 12:37  [ТС]     Как это сделать? #23
Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
Отдельная функция позволяет инициализировать всё в чётко определённый момент и в чётко определённом порядке, прописанном в этой функции. В отличие от.
Отдельную функцию можно вообще забыть вызвать, а если класс буду использовать не я, то можно усомниться даже в знании о необходимости её вызова.

Добавлено через 44 секунды
Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
Обычные глобальные объекты инициализируются чёрти когда. Особенно это касается объектов, определяемых в различных единицах трансляции, которые используют друг друга. Немного цитаток:
Что такое единицы трансляции?
stima
430 / 285 / 16
Регистрация: 22.03.2011
Сообщений: 928
Завершенные тесты: 1
21.04.2013, 12:52     Как это сделать? #24
Цитата Сообщение от taras atavin Посмотреть сообщение
Что такое единицы трансляции?
Обьектники, читайте про раздельную компиляцию.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
21.04.2013, 12:54  [ТС]     Как это сделать? #25
Цитата Сообщение от stima Посмотреть сообщение
Обьектники, читайте про раздельную компиляцию.
Допустим. Но их создание и инициализация всё равно гарантированы.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
21.04.2013, 12:59     Как это сделать? #26
Цитата Сообщение от taras atavin Посмотреть сообщение
Допустим. Но их создание и инициализация всё равно гарантированы.
А порядок — нет. Претензии именно к нему.

Цитата Сообщение от taras atavin Посмотреть сообщение
Отдельную функцию можно вообще забыть вызвать, а если класс буду использовать не я, то можно усомниться даже в знании о необходимости её вызова.
Если её забыть вызвать, то вы тут же получите null pointer dereference exception при первой же попытке тестирования функционала, использующего эти переменные, а не неопределённое поведение из-за инициализации, выполненной в неправильном порядке.

А пользователь может вообще не знать о существовании каких-то глобальных переменных. Если он по религиозным убеждениям не читает документацию, то пусть выкручивается сам.
stima
430 / 285 / 16
Регистрация: 22.03.2011
Сообщений: 928
Завершенные тесты: 1
21.04.2013, 13:02     Как это сделать? #27
Цитата Сообщение от taras atavin Посмотреть сообщение
Допустим. Но их создание и инициализация всё равно гарантированы.
Не допустим, а так оно и есть). Да.

Добавлено через 1 минуту
Ваше решение должно происходить не с точки зрения компиляции, а сточки зрения архитектуры приложения. Вы не стой стороны смотрите.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
21.04.2013, 13:44  [ТС]     Как это сделать? #28
Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
А порядок — нет. Претензии именно к нему.
Во-первых нафиг мне вообще этот порядок? Пусть хоть одновременно создаются. А во-вторых один из параметров конструктора - ссылка на существующий объект. Каким образом может быть нарушен порядок создания и инициализации объектов, если один из них инициируется с использованием ссылки на другой?
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
21.04.2013, 15:09     Как это сделать? #29
То, что объект есть, ещё не значит, что он инициализирован. О возможности косячной инициализации прямым текстом сказано в стандарте, там даже пример есть. И в моей цитате этот кусок тоже есть.

Смотрите, вот есть такие файлы:
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/* == cpp1.h ==== */
#ifndef CPP1_H_
#define CPP1_H_
 
struct A {
    int m_x;
 
    A(int x) : m_x(x) {}
};
 
extern A global1;
 
#endif // CPP1_H_
 
 
/* == cpp1.cpp ==== */
#include "cpp1.h"
 
A global1(42);
 
 
/* == cpp2.h ==== */
 
#ifndef CPP2_H_
#define CPP2_H_
 
#include "cpp1.h"
 
struct B {
    int m_x;
 
    B(const A &a) : m_x(a.m_x) {}
};
 
extern B global2;
 
#endif // CPP2_H_
 
 
/* == cpp2.cpp ==== */
 
#include "cpp2.h"
#include "cpp1.h"
 
B global2(global1);
 
 
/* == main.cpp ==== */
 
#include <iostream>
 
#include "cpp1.h"
#include "cpp2.h"
 
int main()
{
    std::cout << global1.m_x << "\n";
    std::cout << global2.m_x << "\n";
}
Теперь мы их компилим:
Код
c:\Tmp>g++ -c cpp1.cpp

c:\Tmp>g++ -c cpp2.cpp

c:\Tmp>g++ -c main.cpp
А теперь линкуем, но в разном порядке:
Код
c:\Tmp>g++ main.o cpp2.o cpp1.o && a.exe
42
42

c:\Tmp>g++ main.o cpp1.o cpp2.o && a.exe
42
0
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
21.04.2013, 18:32  [ТС]     Как это сделать? #30
Вы ещё предложите готовый экзешник хексом криво отредактировать.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
21.04.2013, 20:20     Как это сделать? #31
Любая другая среда сборки компилирует программы точно так же, здесь нет ни одного выстреливающего в ногу действия. Вы уж как знаете, а лично я не хочу, чтобы поведение моих программ зависело от того, в каком порядке линкер получает объектники.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
22.04.2013, 09:10  [ТС]     Как это сделать? #32
Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
здесь нет ни одного выстреливающего в ногу действия.
А смена порядка?
vxg
Модератор
 Аватар для vxg
2662 / 1673 / 157
Регистрация: 13.01.2012
Сообщений: 6,224
22.04.2013, 13:15     Как это сделать? #33
о! какая тема! а я все почти пропустил(
мне кажется, что это
Цитата Сообщение от taras atavin Посмотреть сообщение
средствами языка запрещено создавать другие экземпляры конструктором по умолчанию
невозможно. а вообще выглядит как фабрика классов - один объект производящий все остальные + приведение типа.
Цитата Сообщение от taras atavin Посмотреть сообщение
ссылку на собственный класс, которая в том числе может ссылаться на экземпляр, созданный конструктором по умолчанию
а это вообще как? если ссылка не на единственный в своем роде объект, то на какой? и зачем в конструктор вообще передавать ссылку?
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
22.04.2013, 13:27  [ТС]     Как это сделать? #34
Цитата Сообщение от vxg Посмотреть сообщение
невозможно. а вообще выглядит как фабрика классов - один объект производящий все остальные + приведение типа.
С какого он производящий то?

Добавлено через 47 секунд
Цитата Сообщение от vxg Посмотреть сообщение
невозможно.
Почему же в сингелтоне возможно?

Добавлено через 2 минуты
Цитата Сообщение от vxg Посмотреть сообщение
а это вообще как? если ссылка не на единственный в своем роде объект, то на какой
У меня не сингелтон. При создании второго ссылка на первый, при создании третьего на любой из первых двух, четвертого - из первых трёх и так далее. При это n первых объектов надо создать таким образом заранее при разработке класса, а остальные прописываются уже в приложении. Первый - единственный, не принимающий ссылок.

Добавлено через 1 минуту
Цитата Сообщение от vxg Посмотреть сообщение
и зачем в конструктор вообще передавать ссылку?
Ну это класс коряги, знающий все её узлы, потомки содержат указатели на предков. Как их ещё инициализировать? И надо гарантировать, что коряга будет ровно одна, а не саксауловы заросли.
vxg
Модератор
 Аватар для vxg
2662 / 1673 / 157
Регистрация: 13.01.2012
Сообщений: 6,224
22.04.2013, 13:59     Как это сделать? #35
Цитата Сообщение от taras atavin Посмотреть сообщение
Почему же в сингелтоне возможно
этого, как и слова сингелтон, я не знаю
делаем так что бы можно было работать только с динамически созданными объектами.
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
36
37
38
39
40
41
42
43
44
45
46
47
48
class node
{
private:
    //поля объекта
    double x;
    double y;
    std::string s;
    node *parent;
 
    //запрещаем создание объектов при помощи конструктора по умолчанию и конструктора копирования
    node(void) {}
    node(const node&) {}
 
    //запрещаем операцию присваивания
    const node &operator =(const node &) {}
 
public:
    static node *root;
 
    static node *create(const double &x, const double &y, const std::string &s, node *parent = 0)
    {
        node *res = 0;
        if (!root)
        {
            if (!parent)
            {
                res = new node;
                res->x = x;
                res->y = y;
                res->s = s;
                res->parent = res;
 
                root = res;
            }
        }
        else if (parent)
        {
            res = new node;
            res->x = x;
            res->y = y;
            res->s = s;
            res->parent = parent;
        }
        return res;
    }
};
 
node *node::root = 0;
Добавлено через 2 минуты
при создании объекта для неправильных объектов будет возвращаться 0. как вариант без динамического создания: выброс исключения из конструктора, но это ад
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
22.04.2013, 14:15  [ТС]     Как это сделать? #36
Цитата Сообщение от vxg Посмотреть сообщение
выброс исключения из конструктора
А можно при этом выдать мессагу, что не так?

Добавлено через 9 минут
И можно реализацию заранее скомпилить с готовыми экземплярами, которые требуется гарантировать, а потом использовать уже lib, или obj?
vxg
Модератор
 Аватар для vxg
2662 / 1673 / 157
Регистрация: 13.01.2012
Сообщений: 6,224
22.04.2013, 14:41     Как это сделать? #37
Цитата Сообщение от taras atavin Посмотреть сообщение
А можно при этом выдать мессагу, что не так
при выбросе (кроме собственно падения программы если выброс нигде не будет словлен) можно сделать все что угодно.
Цитата Сообщение от taras atavin Посмотреть сообщение
И можно реализацию заранее скомпилить с готовыми экземплярами
этого не понял вообще. где-то в программе человек пишет
C++
1
2
3
    node *a = node::create(1, 2, "a", 0); //мы создали root объект
    node *b = node::create(3, 4, "b", 0); //если мы попытаемся еще раз подсунуть в качестве parent ноль (то есть создать еще один root объект) объект не будет создан - будет возвращен ноль
    node *c = node::create(5, 6, "c", a); //а вот так - все нормально
Добавлено через 2 минуты
...а вообще какая-то странная задача. похожа на поиск ошибки при помощи перфоратора... вы по определению не должны создавать еще одного дерева если так задумана архитектура. если вы пытаетесь создать еще одно дерево - у вас не правильный код. отлов ошибок такого рода вмонтированием в класс таких надстроек как то не очень красив
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
22.04.2013, 14:42  [ТС]     Как это сделать? #38
Цитата Сообщение от vxg Посмотреть сообщение
где-то в программе человек пишет
* * node *a = node::create(1, 2, "a", 0); //мы создали root объект
* * node *b = node::create(3, 4, "b", 0); //если мы попытаемся еще раз подсунуть в качестве parent ноль (то есть создать еще один root объект) объект не будет создан - будет возвращен ноль
* * node *c = node::create(5, 6, "c", a); //а вот так - все нормально
Какой ноль?
C++
1
2
3
4
5
6
7
8
9
class A
{
 ...
 private:
 A(); 
...
 public:
 A(A &Base, double k, std::string t);
...
.
vxg
Модератор
 Аватар для vxg
2662 / 1673 / 157
Регистрация: 13.01.2012
Сообщений: 6,224
22.04.2013, 14:46     Как это сделать? #39
...во всяком случае если подобная ошибка не возникает в результате интерактивных действий пользователя (например, он руками строит какието деревья). но в этом случае мы должны помешать ему другим способом и в описанном механизме нет нужды

Добавлено через 35 секунд
ноль - это для варианта когда есть только динамические объекты = есть только указатели.

Добавлено через 1 минуту
если нужен вариант без динамики то либо создавать специальный объект инвалид и после создания при необходимости использовать метод "я_инвалид" либо выбрасывать исключение из конструктора при передаче некорректных параметров

Добавлено через 1 минуту
...интересно должно быть у вас дерево строится на ссылках... получается?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.04.2013, 15:11     Как это сделать?
Еще ссылки по теме:

C++ как это сделать
Как это сделать? C++
C++ нужно создать таблицу из 3 строк и 4 столбцов и заполнить её (любой информацией,это неважно) . Как это можно сделать ?

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
22.04.2013, 15:11  [ТС]     Как это сделать? #40
Цитата Сообщение от vxg Посмотреть сообщение
...интересно должно быть у вас дерево строится на ссылках... получается?
Так я и говорю, что это коряга.
Yandex
Объявления
22.04.2013, 15:11     Как это сделать?
Ответ Создать тему
Опции темы

Текущее время: 09:58. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru