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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 4.65
kravam
быдлокодер
1697 / 884 / 45
Регистрация: 04.06.2008
Сообщений: 5,484
#1

В конструкторе вложенного класса инициализируется приватное поле. Потом вызывается функция-метод этого класса и выводит значение этого поля НО НЕ ТО! - C++

08.06.2011, 00:24. Просмотров 2161. Ответов 21
Метки нет (Все метки)

Друзья! Почему так?
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
#include <windows.h>
#include <iostream>
using namespace std;
 
 
//Вот главный класс
class A{
 private:
 
 //А вот вложенный
 class B { 
  public: 
 
   //А вот инициализация приватного члена i вложенного класса
   B(): i(0){} 
   void operator()(int x){ 
 
    //Ну всё, собсно. Конструктор B создан, i инициализирована должны увидеть 0
    //вместо этого видим чушь
    printf ("i= %d\n", i);
    getchar ();
   } 
  private: 
   int i ; 
 }; 
 
 public:
  A (){};
 
  //А это отдельный разговор, компилится только если возвращает объект типа B
  B B_() {
   B();
  }
};
   
 
int main() {
 A ob_1;
 ob_1.B_()(6);
 system ("pause");
}
Немного по главной функции; итак вызывается конструктор вложенного класса
C++
1
ob_1.B_()
Понятное дело, i должна обнулиться. Так, тут же вызывается фунция переопределения оператора
ob_1.B_()
и я с её помощью очень хочу увидеть ноль, но не вижу. Почему, друзья?

Добавлено через 1 минуту
Последний код читать:
ob_1.B_()(6);
Исправленному верить!!!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.06.2011, 00:24
Здравствуйте! Я подобрал для вас темы с ответами на вопрос В конструкторе вложенного класса инициализируется приватное поле. Потом вызывается функция-метод этого класса и выводит значение этого поля НО НЕ ТО! (C++):

Может ли метод класса возвращать экземпляр этого же класса? - C++
такой вопрос, реально что бы функция класса имела тип класса(возвращала класс), то есть типа так: class c1{ c1 f1(); } если да, то...

Как вызвать виртуальную функцию из дочернего класса, если она определена и вызывается в конструкторе РОДИТЕЛЬСКОГО класса? - C++
Ну то есть так: есть родительский и дочерний класс, в родительском определен виртуальная функция и вызывается в его конструкторе (камень...

Создать шаблонный класс и наследованный от этого класса метод - C++
Создать шаблонный класс и наследованный от этого класса метод(естественно шаблонный), реализовать его в int main(){} через INT и Double.

Сам вопрос: почему функция-член одного класса не вызывается из функции-члена другого класса? - C++
//Щас всё объясню. Так, имеем два класса, в одном я определил функцию-член. Все конструкторы и прочее //опущены для уменьшения кода ...

Возможно ли создание объекта шаблонного класса в функции этого класса? - C++
Доброго времени суток, уважаемые форумчане :) Мне по лабам задали задание - реализовать шаблон контейнера (множество) с операциями...

Построение описания класса, создание и уничтожение объектов этого класса - C++
Построить описание класса, содержащего информацию о почтовом адресе организации. Предусмотреть возможность раздельного изменения...

21
silent_1991
Эксперт С++
4984 / 3041 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
08.06.2011, 11:32 #2
Я несколько не понял некоторые участки вашего кода, поэтому пока выложу код, который выполняет то, что, как я понял, вам надо:

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
#include <iostream>
 
class A
{
    class B
    { 
    public:
        B(int b):
        m_b(b)
        {
        } 
    
        void operator()()
        {
            std::cout << "m_b = " << m_b << std::endl;
        }
    
    private: 
        int m_b; 
    };
 
public:
    A(int a):
    m_a(a)
    {
    }
 
    B get_a() const
    {
        return m_a;
    }
 
private:
    B m_a;
};
   
 
int main()
{
    A a(10);
 
    a.get_a()();
 
    return 0;
}
1
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
08.06.2011, 11:57 #3
это как то подозрительно, хороший компилятор должен обругаться
C++
1
2
3
4
B B_() {
 
   B();
  }
функция ничего не возвращает. Наверно ты хотел
C++
1
2
3
4
B B_() {
 
   return B();
  }
тогда вот эта штука
C++
1
ob_1.B_()
создаст объект класса B, c проинициализированной i = 0.
Затем к этой штуке применяется оператор (), который выводит i=0, а аргумент х впринципе никак не влияет на вывод (). Всё логично, что не так?

Добавлено через 3 минуты
кстати объект, который ты создаёшь таким хитрым способом навсегда теряется в памяти. Наверно лучше сделать что-то типа того
C++
1
2
B &b = ob_1.B_();
b.operator(6);
чтобы с ним работать потом можно было. Ещё меня смущает return B(); мне кажется надо создать в динамической памяти и вернуть на него ссылку, а то как то опасно это выглядит

Добавлено через 5 минут
ты наверно g++ компилировал. Вроде он позволяет делать функции, которые потом ничего не возвращают. Точнее эта штука
C++
1
2
3
4
B B_() {
 
   B();
  }
наверняка что-нибудь вернула, надо посмотреть в дизасме, у меня в ВС это просто не компилируется. Какой-нибудь левый дефолтный адресс, по которому естественно никакого объекта B и впомине не было, соответсвенно i в нём не определенна. Я так думаю
1
silent_1991
Эксперт С++
4984 / 3041 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
08.06.2011, 11:57 #4
pito211, куда это он потеряется? Он уничтожится после вызова operator().
1
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
08.06.2011, 12:01 #5
ну да точно
0
kravam
быдлокодер
1697 / 884 / 45
Регистрация: 04.06.2008
Сообщений: 5,484
08.06.2011, 18:07  [ТС] #6
pito211,тут всё под контролем, ничего возвращать не надо, никаких return. Просто надо вызвать конструктор объекта класса B, что и делается; g++ так разрешает что возвращается не знаю, не интересовался. А вот почему надо в объявлении писать, что функция возвращает B- загадка, иначе ругань.
0
silent_1991
Эксперт С++
4984 / 3041 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
08.06.2011, 18:10 #7
kravam, а чем мой вариант не подходит? Вам обязательно надо было, чтобы класс A не содержал экземпляра класса B? А то так и конструктор естественнее вызывается.
0
kravam
быдлокодер
1697 / 884 / 45
Регистрация: 04.06.2008
Сообщений: 5,484
08.06.2011, 18:16  [ТС] #8
Цитата Сообщение от pito211 Посмотреть сообщение
кстати объект, который ты создаёшь таким хитрым способом навсегда теряется в памяти.
//.............
Какой-нибудь левый дефолтный адресс, по которому естественно никакого объекта B и впомине не было, соответсвенно i в нём не определенна. Я так думаю
молодец,
C++
1
2
3
  B B_() {
   return B();
  }
помогает, посмотрим, что дальше будет.
0
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
08.06.2011, 18:32 #9
Цитата Сообщение от kravam Посмотреть сообщение
А вот почему надо в объявлении писать, что функция возвращает B- загадка, иначе ругань.
а что она должна возвращать? только B
если она как void будет объявлена, то эта штука
Цитата Сообщение от kravam Посмотреть сообщение
ob_1.B_()
возвращает void, а для войда вроде как нет оператора(), на что компилятор и указывает

Добавлено через 7 минут
C++
1
2
3
4
B B_() 
{
 B();
} /*деструктор вызовется тут, поэтому смысла особого нет в этой функции, она вернёт непонятно чё. И приминение оператора() к этому "непонятно чему" ведёт к непредсказуемым последствиям, в лучшем случае выведет кривой i, в худшем SIGSEV. Поэтому return необходим*/
1
kravam
быдлокодер
1697 / 884 / 45
Регистрация: 04.06.2008
Сообщений: 5,484
08.06.2011, 18:46  [ТС] #10
silent_1991,размышляю. Дело в том, что мне в конструкторе не надо передавать значение int (бессмысленн). То есть у меня создаются функции-методы, которые принимают параметрами переменную int
C++
1
2
3
4
5
6
 A ob_1;
 ob_1.B_(89)();
 ob_1.B_(12)();
 ob_1.B_(34)();
 ob_1.B_(42)();
 //И так далее, не конструктор принимает int, а метод!
Повоторяю, это для интерфейса.
И вот, я должен быть уверен, что во внутреннем классе b есть приватное поле, которое
становится равным 89; pito211 сподобил на рабочее

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
#include <windows.h>
#include <iostream>
using namespace std;
 
 
//Вот главный класс
class A{
 private:
 
 //А вот вложенный
 class B { 
  public: 
 
   //А вот инициализация приватного члена i вложенного класса
   B(int z): i(z){} 
   void operator()(){ 
 
    //Была чушь, теперь чё надо!!
    printf ("i= %d\n", i);
    getchar ();
   } 
  private: 
   int i ; 
 }; 
 
 public:
  A (){};
  B B_(int z) {
   return B(z);
  }
};
   
 
int main() {
 A ob_1;
 ob_1.B_(89)();
 system ("pause");
}
Добавлено через 14 минут
pito211,пожалуй, что соглашусь, почему пожалуй, потому, что наблюдаем вызов конструктора классе безо всякого возвращения объекта, тем не менее, к "невозвращённому объекту" применима "operator ()"
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <windows.h>
#include <iostream>
using namespace std;
 
class A{
 public:
  int operator () (int x) {
   return x;
  }         
};
   
 
int main() {
 //Вот здесь
 printf ("A()(6)= %d\n", A()(6));
 system ("pause");
}
,
Хотя, наверное в этом коде тоже присутствует возвращение объекта, просто оно неявное и скрыто где-то внутри кода конструктора и чтобы оно было, компилятор сам заботится об этом, угу?
0
silent_1991
Эксперт С++
4984 / 3041 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
08.06.2011, 18:56 #11
kravam, ну тогда инициализируйте m_a дефолтным значением, а потом, через operator() передавайте нужный параметр. В остальном код отличаться не будет.

Добавлено через 2 минуты
pito211, вообще, если не ошибаюсь, деструктор вызовется после возвращения объекта из функции, однако сразу по возвращении к объекту применяется operator(), поэтому деструктор будет вызван после них.
0
kravam
быдлокодер
1697 / 884 / 45
Регистрация: 04.06.2008
Сообщений: 5,484
08.06.2011, 19:19  [ТС] #12
silent_1991, понятно. Для моей задачи это не подходит вот ещё по какой причине: у меня вложенный класс суть заменитель функции метода. Функция метод вызывается когда она вызывается в коде, а в предложеном вами варианте объект вложенного класса будет вызываться в момент создания объемлюющего объекта. Следовательно, и удаляться будет вместе со своими полями и методами когда будет удалён объемлющий объект, а мне это не подходит, а сейчас пойдут дебри, я их не объяснял просто:

Тут всё завязано со статическими переменными и рекурсивной функцией operator ()... Короче, парни вам это наверное неинтересно, но вы реально круты.
0
silent_1991
Эксперт С++
4984 / 3041 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
08.06.2011, 19:39 #13
kravam, создайте статический объект класса B)))
0
kravam
быдлокодер
1697 / 884 / 45
Регистрация: 04.06.2008
Сообщений: 5,484
08.06.2011, 20:02  [ТС] #14
Имеем:
Рекурсивную функцию-метод,
1)вызывает сама 5 раз (это для простоты, цикл отменяется)
2)Счётчик- статическое поле i, инкременируется в теле функции
3)принимает переменную типа int
синтаксис:
C++
1
ob.f_rek(100);
Так, а повторный вызов
C++
1
ob.f_rek(100);
приведёт к краху, ибо i== 4. Поэтому ищем такой функции аналог объект вложенного класса
++++++++++++++++++++++++++++++++++++++++++++++++++++++
1)вызывается рекурсивная функция "operator ()" 5 раз (это для простоты, цикл отменяется)
2)Счётчик- статическое поле privat i, инициализируется в конструкторе
3)Конструктор принимает переменную типа int

синтаксис:
C++
1
ob.f_rek(100)();
по-моему очень симпатичиный вызов, повторный вызов к краху не приведёт, ибо создастся НОВЫЙ объект f_rek, где i==0.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Исходя из вышенаписанного:
Цитата Сообщение от silent_1991 Посмотреть сообщение
kravam, создайте статический объект класса B)))
что даст?

Добавлено через 1 минуту
самое главное- что рекурсивно 5 раз, иначе и заморочек не было бы
0
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
08.06.2011, 20:23 #15
какие то ты страшные вещи творишь. Интуитивно не понятно, что делает оепратор () и тем более такая конструкция ob.f_rek(100)();
лучше создай статический объект как член класса А, как тебе рекомендовал silent_1991. Тогда он внешне будет вести себя как метод. Для этого собственно и перегружают оператор(), а не для таких извращений ob.f_rek(100)();
0
08.06.2011, 20:23
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.06.2011, 20:23
Привет! Вот еще темы с ответами:

Создать объект внутри класса, который может вызывать функцию этого класса - C++
Ребята помогите уже несколько дней мучаюсь. Хочу сделать программу в консоле демонстрации работы лифта в здании 2 этажа. Сделал класс...

Создание статической функции класса, которая принимает экземпляр этого же класса как объект - C++
Привет. Есть такой код class Model { public: Model(); Model(int verticesSize, int facesSize); ~Model(); static void...

Индексация массива класса, через объект этого класса - C++
class A{ char c;//? - размер массива public: A(int C){c;} }; int main(){ A a(5);//вносим размер массива getch(); ...

Как сделать членом класса экземпляр этого же класса - C++
class Operation { public: bool type; //true = operation, false = number char Operator; Operation L_Op; Operation R_Op; ...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru