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

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

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
SleepMaster
40 / 40 / 1
Регистрация: 26.11.2011
Сообщений: 80
#1

Обращение к приватному члену класса внутри пространства имён - C++

28.11.2011, 16:34. Просмотров 1209. Ответов 19
Метки нет (Все метки)

Здравствуйте.
Вот у меня есть код:
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
#include <iostream>
#include <conio.h>
#include <vector>
#include <string>
using namespace std;
 
namespace Pairs
{
 
class Name_pairs
{
    vector<string> name;
    vector<double> age;
public:
    void read_names(Name_pairs&);
    void read_ages(Name_pairs&);
    void sort(Name_pairs&);
    void print(const Name_pairs&) const;
    vector<string> return_names() { return name; }
    vector<double> return_ages() { return age; }
};
 
ostream& operator<< (ostream& os, const Pairs::Name_pairs& na);
bool operator==(Name_pairs& lna, Name_pairs& rna);
bool operator!=(Name_pairs& lna, Name_pairs& rna);
 
} // namespace Pairs;
 
/* Всё делал в одном и том же файле, лень было создавать другой. 
По правилам да, нужно создать файл .h, но по идее, это не важно. */
 
namespace Pairs {
 
// ... определение функций-членов класса Name_pairs
 
// теперь вопрос.
 
 
ostream& operator<<(ostream& os, const Name_pairs& na)
{
    // как обратится к приватному члену класса???
    for (int i=0; i<na.name.size(); i++) // здесь ошибка: нельзя обратится к name.
        return os << "Name: " << na.name[i] << "\tAge: " << na.age[i]; 
// а также не пойму как реализовать здесь, чтобы выводило на экран в цикле.
}
 
}
 
int main()
{
    Pairs::Name_pairs mine;
    mine.read_names(mine);
    mine.read_ages(mine);
    mine.print(mine);
    mine.sort(mine);
    mine.print(mine);
    getch();
    return 0;
}
Вообще, без namespace Pairs всё работает. Как это исправить?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.11.2011, 16:34     Обращение к приватному члену класса внутри пространства имён
Посмотрите здесь:

C++ Подключение пространства имён
обращение к члену связного списка C++
C++ доступ к приватному члену через нестатическую ссылку
C++ Нужны примеры использования пространства имён
Дружественная функция, объявлённая ранее вне пространства имён класса -> error LNK2019 в Visual Studio 2012 C++
C++ обращение к приватному полю класса
C++ Обращение к переменным одного метода из другого внутри класса
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Bers
Заблокирован
28.11.2011, 16:41     Обращение к приватному члену класса внутри пространства имён #2
Цитата Сообщение от SleepMaster Посмотреть сообщение
Вообще, без namespace Pairs всё работает. Как это исправить?
using namespace Pairs

Не?
sandye51
программист С++
677 / 579 / 39
Регистрация: 19.12.2010
Сообщений: 2,016
28.11.2011, 16:53     Обращение к приватному члену класса внутри пространства имён #3
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
#include <iostream>
#include <vector>
#include <string>
 
namespace Pairs
{
    class Name_pairs
    {
            std::vector<std::string> name;
            std::vector<double> age;
    public:
            void read_names(Name_pairs&);
            void read_ages(Name_pairs&);
            void sort(Name_pairs&);
            void print(const Name_pairs&) const;
 
            const std::vector<std::string>& return_names() const
            {
                return name;
            }
            const std::vector<double>& return_ages() const
            {
                return age;
            }
 
            friend std::ostream& operator<< (std::ostream& os, const Pairs::Name_pairs& na);
    };
 
    bool operator==(Name_pairs& lna, Name_pairs& rna);
    bool operator!=(Name_pairs& lna, Name_pairs& rna);
 
}
 
namespace Pairs
{
 
    std::ostream& operator<<(std::ostream& os, const Name_pairs& na)
    {
        for (unsigned int i = 0, end = na.name.size(); i < end; i++)
            os << "Name: " << na.name[i] << "\tAge: " << na.age[i] << std::endl;
        return os;
    }
}
 
int main()
{
        Pairs::Name_pairs mine;
//        mine.read_names(mine);
//        mine.read_ages(mine);
//        mine.print(mine);
//        mine.sort(mine);
//        mine.print(mine);
 
        return 0;
}
чтобы обратиться к приватному члену класса из какой либо функции (или оператора), например func, то надо сделать ее дружественной для этого класса
C++
1
2
3
4
5
6
7
8
9
10
11
class test
{
friend void func();
private:
int value;
};
 
void func(test obj)
{
obj.value = 1;  // ошибки нет
}
вызов других функций закомментил, т.к. не реализованы они у тебя еще.
SleepMaster
40 / 40 / 1
Регистрация: 26.11.2011
Сообщений: 80
28.11.2011, 17:07  [ТС]     Обращение к приватному члену класса внутри пространства имён #4
Цитата Сообщение от Bers Посмотреть сообщение
using namespace Pairs
Да . Но теперь два других вопроса:
в теле
C++
1
2
3
4
5
ostream& operator<<(ostream& os, const Name_pairs& na)
{
        for (int i=0; i<na.name.size(); i++)
                return os << "Name: " << na.name[i] << "\tAge: " << na.age[i];
}
Нельзя использовать for, return, пишет что: требуется объявление.
И как мне вывести в цикле вектор?

Добавлено через 10 минут
Вобщем, вот вся программа, мне не жалко. Помогите с одной функцией:
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <iostream>
#include <conio.h>
#include <vector>
#include <string>
using namespace std;
 
namespace Pairs
{
 
class Name_pairs
{
    vector<string> name;
    vector<double> age;
public:
    void read_names(Name_pairs&);
    void read_ages(Name_pairs&);
    void sort(Name_pairs&);
    void print(const Name_pairs&) const;
    vector<string> return_names() { return name; }
    vector<double> return_ages() { return age; }
 
};
 
ostream& operator<< (ostream& os, const Pairs::Name_pairs& na);
bool operator==(Name_pairs& lna, Name_pairs& rna);
bool operator!=(Name_pairs& lna, Name_pairs& rna);
 
}
 
using namespace Pairs {
 
void Name_pairs::read_names(Name_pairs &na)
{
    string val;
    while (cin>>val&&val!="Q")
        na.name.push_back(val);
}
 
void Name_pairs::read_ages(Name_pairs &a)
{
    double val;
    for (int i=0; i<a.name.size(); i++)
        { cin >> val;
            a.age.push_back(val); }
}
 
void Name_pairs::sort(Name_pairs& n)
{
    bool key = true;
    while (key) {
        key = false;
            for (int i=0; i<n.name.size()-1; i++)
                if (n.name[i+1]<n.name[i])
                {
                    swap(n.name[i+1], n.name[i]);
                    swap(n.age[i+1], n.age[i]);
                    key = true;
                }
    }
}
 
void Name_pairs::print(const Name_pairs& na) const
{
    for (int i=0; i<na.name.size(); i++)
        cout << na.name[i] << '\t' << na.age[i];
}
 
ostream& operator<<(ostream& os, const Name_pairs& na)
{
    /* помогите реализовать эту функцию */
    for (int i=0; i<na.name.size(); i++) 
        return os << "Name: " << na.name[i] << "\tAge: " << na.age[i];
}
 
}
 
int main()
{
    Pairs::Name_pairs mine;
    mine.read_names(mine);
    mine.read_ages(mine);
    mine.print(mine);
    mine.sort(mine);
    mine.print(mine);
    getch();
    return 0;
}
sandye51
программист С++
677 / 579 / 39
Регистрация: 19.12.2010
Сообщений: 2,016
28.11.2011, 17:08     Обращение к приватному члену класса внутри пространства имён #5
Цитата Сообщение от SleepMaster Посмотреть сообщение
омогите с одной функцией:
смотри мой код, она там реализована
SleepMaster
40 / 40 / 1
Регистрация: 26.11.2011
Сообщений: 80
28.11.2011, 17:10  [ТС]     Обращение к приватному члену класса внутри пространства имён #6
Цитата Сообщение от sandye51 Посмотреть сообщение
смотри мой код, она там реализована
Но там она реализована внутри класса, да? Мне нужно, чтобы она была реализована вне класса внутри пространства имён. Так возможно вообще?
Bers
Заблокирован
28.11.2011, 17:12     Обращение к приватному члену класса внутри пространства имён #7
избегай френдов, как огня - окажешь себе большую услугу
SleepMaster
40 / 40 / 1
Регистрация: 26.11.2011
Сообщений: 80
28.11.2011, 17:17  [ТС]     Обращение к приватному члену класса внутри пространства имён #8
Спасибо, тупанул, всё работает
sandye51
программист С++
677 / 579 / 39
Регистрация: 19.12.2010
Сообщений: 2,016
28.11.2011, 17:19     Обращение к приватному члену класса внутри пространства имён #9
Цитата Сообщение от SleepMaster Посмотреть сообщение
вне класса внутри пространства имён. Так возможно вообще?
дружественные функции по определению вне класса, даже если реализованы внутри него
SleepMaster
40 / 40 / 1
Регистрация: 26.11.2011
Сообщений: 80
28.11.2011, 17:28  [ТС]     Обращение к приватному члену класса внутри пространства имён #10
Цитата Сообщение от Bers Посмотреть сообщение
избегай френдов, как огня - окажешь себе большую услугу
Предложите альтернативу
Bers
Заблокирован
28.11.2011, 17:32     Обращение к приватному члену класса внутри пространства имён #11
Цитата Сообщение от SleepMaster Посмотреть сообщение
Предложите альтернативу
Плясать нужно не от формального дееспособного кода.
А от конкретной задачи, которую этот код решает.

Можно конечно исследовать сам код, и догадаться по его поведению, какую задачу он решает.
Но по моему проще, просто спросить об этом у автора. М?

Автор до этого момента как то не озаботился сообщить, что должен делать его код.
sandye51
программист С++
677 / 579 / 39
Регистрация: 19.12.2010
Сообщений: 2,016
28.11.2011, 17:35     Обращение к приватному члену класса внутри пространства имён #12
Цитата Сообщение от SleepMaster Посмотреть сообщение
Предложите альтернативу
можно сделать чтобы функций не напрямую обращалась к полю, а вызывала какой нить метод, типо get_name() и с ним работала уже
SleepMaster
40 / 40 / 1
Регистрация: 26.11.2011
Сообщений: 80
28.11.2011, 17:49  [ТС]     Обращение к приватному члену класса внутри пространства имён #13
Два метода на ввод векторов, которые принадлежат классу Name_pairs. Одна print, которую я как раз и хочу заменить на ostream& operator<<. sort() - сортирует класс по именам, с привязкой возрастов. И ещё две, которые просто возвращают вектора name и age. Но это абсолютно не важно уже. Всё что я хотел выяснить, это как можно было обойтись без friend'ов.
Сыроежка
Заблокирован
28.11.2011, 18:22     Обращение к приватному члену класса внутри пространства имён #14
SleepMaster,

У вас класс спроектирован некорректно. Расммотрим функцию

C++
1
2
3
4
5
6
void Name_pairs::read_names(Name_pairs &na)
{
        string val;
        while (cin>>val&&val!="Q")
                na.name.push_back(val);
}
Эта функция ничего не делает с ттем объектом, который ее вызвал. То есть она не меняет объект, который вызывает функцию. Она меняет тот объект, который вы передали в качестве параметра. Поэтому, когда функция не изменяет объект, который ее вызывает, то лучше эту функцию сделать статической.

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

C++
1
2
3
4
5
void Name_pairs::read_names()
{
        string val;
        while ( cin >> va l&& val !="Q" ) name.push_back( val );
}
В этом случае функция заполняет вектор не того объекта, который был передан в качестве параметра функции, а именно тот сам объект, который вызвал ее.
SleepMaster
40 / 40 / 1
Регистрация: 26.11.2011
Сообщений: 80
28.11.2011, 18:49  [ТС]     Обращение к приватному члену класса внутри пространства имён #15
Хорошо. Объясню, как я это понимаю:
friend используется, если мы хотим предоставить обычной функции доступ к закрытым и защищенным членам класса. Однако, внутри friend'овской функции нельзя использовать static и extern, отсюда и ограничение на использование.
Bers
Заблокирован
28.11.2011, 18:51     Обращение к приватному члену класса внутри пространства имён #16
Цитата Сообщение от SleepMaster Посмотреть сообщение
friend используется, если мы хотим предоставить обычной функции доступ к закрытым и защищенным членам класса. Однако, внутри friend'овской функции нельзя использовать static и extern.
Сам факт предоставления кому бы то ни было "закрытых" данных уже пахнет нарушением инкапсуляции. Этого нужно избегать настолько, насколько это вообще возможно.

Или пиши все сразу в паблике, и не парься.
SleepMaster
40 / 40 / 1
Регистрация: 26.11.2011
Сообщений: 80
28.11.2011, 19:03  [ТС]     Обращение к приватному члену класса внутри пространства имён #17
Тогда вопрос:
Как обойтись без frienda в этом
коде

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <iostream>
#include <conio.h>
#include <vector>
#include <string>
using namespace std;
 
namespace Pairs
{
 
class Name_pairs
{
    vector<string> name;
    vector<double> age;
public:
    void read_names(Name_pairs&);
    void read_ages(Name_pairs&);
    void sort(Name_pairs&);
    void print(const Name_pairs&) const;
    vector<string> return_names() { return name; }
    vector<double> return_ages() { return age; }
    friend ostream& operator<< (ostream& os, const Pairs::Name_pairs& na);
};
 
bool operator==(Name_pairs& lna, Name_pairs& rna);
bool operator!=(Name_pairs& lna, Name_pairs& rna);
 
}
 
namespace Pairs
{
 
void Name_pairs::read_names(Name_pairs &na)
{
    string val;
    while (cin>>val&&val!="Q")
        na.name.push_back(val);
}
 
void Name_pairs::read_ages(Name_pairs &a)
{
    double val;
    for (int i=0; i<a.name.size(); i++)
        { cin >> val;
            a.age.push_back(val); }
}
 
void Name_pairs::sort(Name_pairs& n)
{
    bool key = true;
    while (key) {
        key = false;
            for (int i=0; i<n.name.size()-1; i++)
                if (n.name[i+1]<n.name[i])
                {
                    swap(n.name[i+1], n.name[i]);
                    swap(n.age[i+1], n.age[i]);
                    key = true;
                }
    }
}
 
void Name_pairs::print(const Name_pairs& na) const
{
    for (int i=0; i<na.name.size(); i++)
        cout << na.name[i] << '\t' << na.age[i];
}
 
ostream& operator<<(ostream& os, const Name_pairs& na)
{
        for (unsigned int i = 0, end = na.name.size(); i < end; i++)
            os << "Name: " << na.name[i] << "\tAge: " << na.age[i] << std::endl;
        return os;
}
 
}
 
int main()
{
    Pairs::Name_pairs mine;
    mine.read_names(mine);
    mine.read_ages(mine);
    cout<<mine;
    mine.sort(mine);
    cout<<mine;
    getch();
    return 0;
}
Не нужно исправлять других ошибок, я знаю что код требует доработки. Просто перепишите функцию
operator<<
C++
1
2
3
4
5
6
ostream& operator<<(ostream& os, const Name_pairs& na)
{
        for (unsigned int i = 0, end = na.name.size(); i < end; i++)
            os << "Name: " << na.name[i] << "\tAge: " << na.age[i] << std::endl;
        return os;
}
так, чтобы она не использовала friendов.
sandye51
программист С++
677 / 579 / 39
Регистрация: 19.12.2010
Сообщений: 2,016
28.11.2011, 19:07     Обращение к приватному члену класса внутри пространства имён #18
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <iostream>
#include <conio.h>
#include <vector>
#include <string>
using namespace std;
 
namespace Pairs
{
 
class Name_pairs
{
        vector<string> name;
        vector<double> age;
public:
        void read_names(Name_pairs&);
        void read_ages(Name_pairs&);
        void sort(Name_pairs&);
        void print(const Name_pairs&) const;
        const vector<string>& return_names() const { return name; }
        const vector<double>& return_ages() const { return age; }
};
 
bool operator==(Name_pairs& lna, Name_pairs& rna);
bool operator!=(Name_pairs& lna, Name_pairs& rna);
 
}
 
namespace Pairs
{
 
void Name_pairs::read_names(Name_pairs &na)
{
        string val;
        while (cin>>val&&val!="Q")
                na.name.push_back(val);
}
 
void Name_pairs::read_ages(Name_pairs &a)
{
        double val;
        for (unsigned int i=0; i<a.name.size(); i++)
                { cin >> val;
                        a.age.push_back(val); }
}
 
void Name_pairs::sort(Name_pairs& n)
{
        bool key = true;
        while (key) {
                key = false;
                        for (unsigned int i=0; i<n.name.size()-1; i++)
                                if (n.name[i+1]<n.name[i])
                                {
                                        swap(n.name[i+1], n.name[i]);
                                        swap(n.age[i+1], n.age[i]);
                                        key = true;
                                }
        }
}
 
void Name_pairs::print(const Name_pairs& na) const
{
        for (unsigned int i=0; i<na.name.size(); i++)
                cout << na.name[i] << '\t' << na.age[i];
}
 
ostream& operator<<(ostream& os, const Name_pairs& na)
{
    const std::vector<std::string>& names = na.return_names();
    const std::vector<double>& ages = na.return_ages();
 
    for (unsigned int i = 0, end = names.size(); i < end; i++)
        os << "Name: " << names[i] << "\tAge: " << ages[i] << std::endl;
    return os;
}
 
}
 
int main()
{
        Pairs::Name_pairs mine;
        mine.read_names(mine);
        mine.read_ages(mine);
        cout<<mine;
        mine.sort(mine);
        cout<<mine;
        getch();
        return 0;
}
очень просто
Bers
Заблокирован
28.11.2011, 19:08     Обращение к приватному члену класса внутри пространства имён #19
SleepMaster, да код написать не сложно, только у тебя ж от этого в голове ума не прибавиться.

Ты пойми, идею нужно понимать, а не то, как её реализовать
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.11.2011, 19:18     Обращение к приватному члену класса внутри пространства имён
Еще ссылки по теме:

C++ Обращение к члену protected
Обращение потока к функции-члену класса C++
C++ Undefined reference to. и пространства имён
Пространства имён с++ C++
C++ Обращение к члену структуры

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

Или воспользуйтесь поиском по форуму:
SleepMaster
40 / 40 / 1
Регистрация: 26.11.2011
Сообщений: 80
28.11.2011, 19:18  [ТС]     Обращение к приватному члену класса внутри пространства имён #20
sandye51, Благодарю. Считаю, что тему можно закрыть.
Yandex
Объявления
28.11.2011, 19:18     Обращение к приватному члену класса внутри пространства имён
Ответ Создать тему
Опции темы

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