Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.62/13: Рейтинг темы: голосов - 13, средняя оценка - 4.62
kravam
быдлокодер
1714 / 901 / 106
Регистрация: 04.06.2008
Сообщений: 5,588
1

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

08.06.2011, 00:24. Просмотров 2530. Ответов 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
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.06.2011, 00:24
Ответы с готовыми решениями:

Можно ли сделать поле класса параметром функции-члена этого же класса?
Здраствуйте. ref class MyClass { private: int i, j; array&lt;array&lt;int&gt;^&gt;^ X1; ...

Как вызвать метод класса в другом методе этого же класса?
&lt;? class load_files{ public function traverse_hierarchy($path) { // from...

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

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

Как связать сигнал одного класса со слотом другого класса, содержащего указатель на объект этого класса?
Подскажите, пожалуйста, как связать сигнал одного класса со слотом другого класса, содержащего...

21
silent_1991
Эксперт С++
5023 / 3083 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
Завершенные тесты: 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 / 18
Регистрация: 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
Эксперт С++
5023 / 3083 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
Завершенные тесты: 1
08.06.2011, 11:57 4
pito211, куда это он потеряется? Он уничтожится после вызова operator().
1
08.06.2011, 11:57
pito211
186 / 173 / 18
Регистрация: 22.03.2010
Сообщений: 612
08.06.2011, 12:01 5
ну да точно
0
kravam
быдлокодер
1714 / 901 / 106
Регистрация: 04.06.2008
Сообщений: 5,588
08.06.2011, 18:07  [ТС] 6
pito211,тут всё под контролем, ничего возвращать не надо, никаких return. Просто надо вызвать конструктор объекта класса B, что и делается; g++ так разрешает что возвращается не знаю, не интересовался. А вот почему надо в объявлении писать, что функция возвращает B- загадка, иначе ругань.
0
silent_1991
Эксперт С++
5023 / 3083 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
Завершенные тесты: 1
08.06.2011, 18:10 7
kravam, а чем мой вариант не подходит? Вам обязательно надо было, чтобы класс A не содержал экземпляра класса B? А то так и конструктор естественнее вызывается.
0
kravam
быдлокодер
1714 / 901 / 106
Регистрация: 04.06.2008
Сообщений: 5,588
08.06.2011, 18:16  [ТС] 8
Цитата Сообщение от pito211 Посмотреть сообщение
кстати объект, который ты создаёшь таким хитрым способом навсегда теряется в памяти.
//.............
Какой-нибудь левый дефолтный адресс, по которому естественно никакого объекта B и впомине не было, соответсвенно i в нём не определенна. Я так думаю
молодец,
C++
1
2
3
  B B_() {
   return B();
  }
помогает, посмотрим, что дальше будет.
0
pito211
186 / 173 / 18
Регистрация: 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
быдлокодер
1714 / 901 / 106
Регистрация: 04.06.2008
Сообщений: 5,588
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
Эксперт С++
5023 / 3083 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
Завершенные тесты: 1
08.06.2011, 18:56 11
kravam, ну тогда инициализируйте m_a дефолтным значением, а потом, через operator() передавайте нужный параметр. В остальном код отличаться не будет.

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

Тут всё завязано со статическими переменными и рекурсивной функцией operator ()... Короче, парни вам это наверное неинтересно, но вы реально круты.
0
silent_1991
Эксперт С++
5023 / 3083 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
Завершенные тесты: 1
08.06.2011, 19:39 13
kravam, создайте статический объект класса B)))
0
kravam
быдлокодер
1714 / 901 / 106
Регистрация: 04.06.2008
Сообщений: 5,588
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 / 18
Регистрация: 22.03.2010
Сообщений: 612
08.06.2011, 20:23 15
какие то ты страшные вещи творишь. Интуитивно не понятно, что делает оепратор () и тем более такая конструкция ob.f_rek(100)();
лучше создай статический объект как член класса А, как тебе рекомендовал silent_1991. Тогда он внешне будет вести себя как метод. Для этого собственно и перегружают оператор(), а не для таких извращений ob.f_rek(100)();
0
silent_1991
Эксперт С++
5023 / 3083 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
Завершенные тесты: 1
08.06.2011, 20:30 16
Такая рекурсия не катит?

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
#include <iostream>
 
void rec_func_five_times(int x)
{
    static int i = 0;
 
    if (i == 5)
    {
        i = 0;
 
        std::cout << std::endl;
 
        return;
    }
 
    std::cout << x << "  ";
 
    ++i;
 
    rec_func_five_times(x + 1);
}
 
int main()
{
    rec_func_five_times(1);
    rec_func_five_times(2);
    rec_func_five_times(3);
 
    return 0;
}
0
kravam
быдлокодер
1714 / 901 / 106
Регистрация: 04.06.2008
Сообщений: 5,588
08.06.2011, 20:40  [ТС] 17
Не катит абсолютно. Вы поймите мне нужен более или менее единообразный интерфейс. То есть:
создание объекта, вызов функции метода, которая определена для этого объекта. (И она должна быть объявлена в теле класса ещё. Чтобы класс был полон и всё объявления присутствовали в нём)
C++
1
2
3
Ob ob;
ob.f_0(); 
ob.f_1_rek(5)();
А функция
rec_func_five_timesпри всей её работоспособности она сама по себе, она не метод.
0
silent_1991
Эксперт С++
5023 / 3083 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
Завершенные тесты: 1
08.06.2011, 20:44 18
kravam, и что мешает сделать её методом?
0
kravam
быдлокодер
1714 / 901 / 106
Регистрация: 04.06.2008
Сообщений: 5,588
08.06.2011, 21:06  [ТС] 19
Ну я делал-делал, делал-делал, в результате появилась эта тема.
Я же говорю: В функции должно быть определена статическая переменная. Блин
C++
1
2
ob.rec_func_five_times (90);
ob.rec_func_five_times (89);
ВСё, приплыли. Первый вызов отработает 5 раз. А второй? 0 раз! Ибо i будет равна 5! А мне всякий раз нудо чтобы i была равна 0! При каждом таком вызове!
C++
1
2
3
ob.rec_func_five_times (90);
ob.rec_func_five_times (89);
ob.rec_func_five_times (35);

Цитата Сообщение от pito211 Посмотреть сообщение
лучше создай статический объект как член класса А, как тебе рекомендовал silent_1991. Тогда он внешне будет вести себя как метод.
Да не пойдёт же
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
 
class A {
 class B {;
  public:
   B ():i(0) {};
 
  private:
   int i;          
 };
 static B b;
};        
 
int main(){
    getchar ();
    return 0;
}
И по этому вопросу я говорил уже: B создастся при создании класса A ОДИН РАЗ и приватная переменная i обнуляться НЕ БУДЕТ
0
silent_1991
Эксперт С++
5023 / 3083 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
Завершенные тесты: 1
08.06.2011, 21:12 20
Похоже, я просто не могу понять, чего вы добиваетесь...

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
#include <iostream>
 
class Foo
{
public:
    void rec_method_five_times(int x)
    {
        static int i = 0;
 
        if (i == 5)
        {
            i = 0;
 
            std::cout << std::endl;
 
            return;
        }
 
        std::cout << x << "  ";
 
        ++i;
 
        rec_method_five_times(x + 1);
    }
};
 
int main()
{
    Foo bar;
 
    bar.rec_method_five_times(1);
    bar.rec_method_five_times(2);
    bar.rec_method_five_times(3);
 
    return 0;
}
1
08.06.2011, 21:12
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.06.2011, 21:12

Как вызвать метод вложенного класса в методе родительского класса
Имеется родительский класс для прорисовки графики Jogj package objects; import...

Создать шаблонный класс и наследованный от этого класса метод
Создать шаблонный класс и наследованный от этого класса метод(естественно шаблонный), реализовать...

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


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

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

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