40 / 40 / 7
Регистрация: 26.11.2011
Сообщений: 80
1

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

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

Author24 — интернет-сервис помощи студентам
Здравствуйте.
Вот у меня есть код:
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 всё работает. Как это исправить?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.11.2011, 16:34
Ответы с готовыми решениями:

Обращение к приватному полю класса
class CMessage { char *pmessage; public: void ShowIt() { cout&lt;&lt;endl&lt;&lt;pmessage&lt;&lt;endl;...

Обращение потока к функции-члену класса
Есть Класс MainWindow, функцией-членом которой выступает Reader(), при попытке обратиться поток к...

Доступ к приватному члену через нестатическую ссылку
Привет всем. забуксовал.. подтолкните пжалста: ситуация: - в хедере class A { private: int...

Дружественная функция, объявлённая ранее вне пространства имён класса -> error LNK2019 в Visual Studio 2012
Всем привет. Долгое время пытался откопать ответ в гугле, но не получилось. Заранее благодарен. ...

19
Заблокирован
28.11.2011, 16:41 2
Цитата Сообщение от SleepMaster Посмотреть сообщение
Вообще, без namespace Pairs всё работает. Как это исправить?
using namespace Pairs

Не?
1
программист С++
860 / 600 / 147
Регистрация: 19.12.2010
Сообщений: 2,014
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;  // ошибки нет
}
вызов других функций закомментил, т.к. не реализованы они у тебя еще.
1
40 / 40 / 7
Регистрация: 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;
}
0
программист С++
860 / 600 / 147
Регистрация: 19.12.2010
Сообщений: 2,014
28.11.2011, 17:08 5
Цитата Сообщение от SleepMaster Посмотреть сообщение
омогите с одной функцией:
смотри мой код, она там реализована
1
40 / 40 / 7
Регистрация: 26.11.2011
Сообщений: 80
28.11.2011, 17:10  [ТС] 6
Цитата Сообщение от sandye51 Посмотреть сообщение
смотри мой код, она там реализована
Но там она реализована внутри класса, да? Мне нужно, чтобы она была реализована вне класса внутри пространства имён. Так возможно вообще?
0
Заблокирован
28.11.2011, 17:12 7
избегай френдов, как огня - окажешь себе большую услугу
0
40 / 40 / 7
Регистрация: 26.11.2011
Сообщений: 80
28.11.2011, 17:17  [ТС] 8
Спасибо, тупанул, всё работает
0
программист С++
860 / 600 / 147
Регистрация: 19.12.2010
Сообщений: 2,014
28.11.2011, 17:19 9
Цитата Сообщение от SleepMaster Посмотреть сообщение
вне класса внутри пространства имён. Так возможно вообще?
дружественные функции по определению вне класса, даже если реализованы внутри него
0
40 / 40 / 7
Регистрация: 26.11.2011
Сообщений: 80
28.11.2011, 17:28  [ТС] 10
Цитата Сообщение от Bers Посмотреть сообщение
избегай френдов, как огня - окажешь себе большую услугу
Предложите альтернативу
0
Заблокирован
28.11.2011, 17:32 11
Цитата Сообщение от SleepMaster Посмотреть сообщение
Предложите альтернативу
Плясать нужно не от формального дееспособного кода.
А от конкретной задачи, которую этот код решает.

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

Автор до этого момента как то не озаботился сообщить, что должен делать его код.
0
программист С++
860 / 600 / 147
Регистрация: 19.12.2010
Сообщений: 2,014
28.11.2011, 17:35 12
Цитата Сообщение от SleepMaster Посмотреть сообщение
Предложите альтернативу
можно сделать чтобы функций не напрямую обращалась к полю, а вызывала какой нить метод, типо get_name() и с ним работала уже
1
40 / 40 / 7
Регистрация: 26.11.2011
Сообщений: 80
28.11.2011, 17:49  [ТС] 13
Два метода на ввод векторов, которые принадлежат классу Name_pairs. Одна print, которую я как раз и хочу заменить на ostream& operator<<. sort() - сортирует класс по именам, с привязкой возрастов. И ещё две, которые просто возвращают вектора name и age. Но это абсолютно не важно уже. Всё что я хотел выяснить, это как можно было обойтись без friend'ов.
0
Заблокирован
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 );
}
В этом случае функция заполняет вектор не того объекта, который был передан в качестве параметра функции, а именно тот сам объект, который вызвал ее.
2
40 / 40 / 7
Регистрация: 26.11.2011
Сообщений: 80
28.11.2011, 18:49  [ТС] 15
Хорошо. Объясню, как я это понимаю:
friend используется, если мы хотим предоставить обычной функции доступ к закрытым и защищенным членам класса. Однако, внутри friend'овской функции нельзя использовать static и extern, отсюда и ограничение на использование.
0
Заблокирован
28.11.2011, 18:51 16
Цитата Сообщение от SleepMaster Посмотреть сообщение
friend используется, если мы хотим предоставить обычной функции доступ к закрытым и защищенным членам класса. Однако, внутри friend'овской функции нельзя использовать static и extern.
Сам факт предоставления кому бы то ни было "закрытых" данных уже пахнет нарушением инкапсуляции. Этого нужно избегать настолько, насколько это вообще возможно.

Или пиши все сразу в паблике, и не парься.
0
40 / 40 / 7
Регистрация: 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ов.
0
программист С++
860 / 600 / 147
Регистрация: 19.12.2010
Сообщений: 2,014
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;
}
очень просто
1
Заблокирован
28.11.2011, 19:08 19
SleepMaster, да код написать не сложно, только у тебя ж от этого в голове ума не прибавиться.

Ты пойми, идею нужно понимать, а не то, как её реализовать
0
40 / 40 / 7
Регистрация: 26.11.2011
Сообщений: 80
28.11.2011, 19:18  [ТС] 20
sandye51, Благодарю. Считаю, что тему можно закрыть.
0
28.11.2011, 19:18
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.11.2011, 19:18
Помогаю со студенческими работами здесь

Обращение к переменным одного метода из другого внутри класса
Доброго времени суток. Поставлена задача написать программу реализующую матрицу и поостые...

Обращение к члену структуры
В чем разница между: a-&gt;b и a.b

Обращение к члену protected
Добрый день, помогите разобраться Обращение к члену protected, сообщается ошибкой Код класса:...

Пространства имён с++
Может я отсталый совсем, но перечислите пожалуйста все известные вам пространства имён в с++


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru