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

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

Войти
Регистрация
Восстановить пароль
 
relationer
33 / 0 / 0
Регистрация: 07.11.2013
Сообщений: 118
#1

Запрещение переинициализации public-поля как члена класса - C++

20.06.2014, 16:58. Просмотров 317. Ответов 3
Метки нет (Все метки)

Здравствуйте!

Предположим, у нас есть некий класс, в нем есть public-поле, которое выполняет некоторые служебные функции.
Нужно запретить вызов конструктора поля отовсюду, кроме как из основного класса, т. е. нельзя написать:
C++
1
2
3
4
5
6
7
8
9
10
11
class A
{
public:
    B field;
 
    A() : field { }
    { }
};
/* *** */
A a { };
a.field = B(); // baaad!
При этом, необходимо, чтобы пользователь вызывал неконстантные методы поля.
Объявить в типе поля основной класс как friend и сделать приватный конструктор невозможно - класс универсальный.
Можно сделать объявление поля через const, но тогда почти все внутренние поля придется объявлять как mutable.

Вопрос. Как подобное лучше всего сделать?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.06.2014, 16:58
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Запрещение переинициализации public-поля как члена класса (C++):

Запрещение перегрузки public методов базового класса - C++
Можно ли запретить наследникам перегружать public методы базового класса? Если да то как? class base { public: void...

Наследования класса как public, private и protected - C++
Ну допустим у нас есть класс который наследуется как public: class Cylinder : public Point { // ...здесь код } Класс...

Определить операторы как функции члена класса - C++
Добрый вечер! Ребята, помогите решить вот такую задачку: Необходимо определить операторы +, =, +=, -=, *=, , как функции члена...

Создать конструктор для массива, как члена класса - C++
Добрый день! Если одним из членов класса, является массив, какой конструктор может для него использоваться, как он выглядит?

Как создать гетер для члена класса с типом bool? - C++
Всем привет!!! У меня есть класс и его экземпляр NameDialog dialogNameFile, созданный в классе GuiInteraction. В функциях класса...

Создать конструктор копий и оператор присваивания для класса компьютер и члена класса марка - C++
Создать конструктор копий и оператор присваивания для класса компьютер и члена класса марка. Всем огромное спасибо за помощь! |

3
Croessmah
Эксперт CЭксперт С++
13513 / 7671 / 866
Регистрация: 27.09.2012
Сообщений: 18,870
Записей в блоге: 3
Завершенные тесты: 1
20.06.2014, 17:36 #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
{
public:
   int x ;
   int get () {
      return x ;
   }
} ;
 
 
template < typename T >
class wrap : public T
{
   friend class Test ;
   wrap operator= ( const wrap & ) { /*...*/ }
   wrap ( const wrap & ) { /*...*/ }
public:
   wrap () : T() { /*...*/ }
} ;
 
 
class Test
{
public:
   wrap<A> d ;
 
   Test ( int x ) {
      d.x = x ;
   }
} ;
 
 
 
 
int main(){
   Test t(40) ;
   A a1 ;
   A a2 ;
   a1=a2 ;
   t.d = a1 ;//Error
   std::cout << t.d.get() << std::endl ;
}
что-то в этом роде? Хотя я и не совсем понял зачем это нужно
0
relationer
33 / 0 / 0
Регистрация: 07.11.2013
Сообщений: 118
20.06.2014, 19:44  [ТС] #3
Ну, этот способ мне не подходит. Слишком напрягает wrap.

Для чего: хочу сделать простую модель событий с использованием а-ля C#. Т. е. что-то типа:
C++
1
Button.onPress += myHandler;
Класс я написал, точнее шаблон, и работает это как-то так:
C++
1
2
3
// button.hpp
struct OnPressEventArgument { int some; }
Event<OnPressEventArgument> OnPress = { };
Т. е. очень лёгкий способ написания событий. Проблема в том, что юзер может написать так:
C++
1
button.OnPress = Event< ... >();
Как это предотвратить?
0
Avazart
Нарушитель
Эксперт С++
7232 / 5404 / 293
Регистрация: 10.12.2010
Сообщений: 23,951
Записей в блоге: 17
21.06.2014, 01:48 #4
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
C++
1
Button.onPress += myHandler;
Именно так не выйдет, точнее сказать так не принято в С++, ибо в С++ нет свойств, всё через геттеры и сетторы, поэтому будет выглядеть как-то так:
C++
1
Button.addOnPress(myHandler);
И то что приведено в первом посте ошибочно
C++
1
2
public:
    B field;
Открытых членов не должно быть, опять же через сеттеры/геттеры.

Добавлено через 27 минут
Приблизительно так:
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
#include <iostream>
#include <vector>
#include <string>
 
class Object
{
    public:
        virtual std::string className(){ return "Object"; };
        virtual ~Object(){};
};
 
typedef void (*Function)(Object* obj);
 
void f1(Object* sender)
{
    std::cout<<sender->className()<<": f1()"<<std::endl;
}
 
void f2(Object* sender)
{
    std::cout<<sender->className()<<": f2()"<<std::endl;
}
 
template <typename FunctionT>
class Event
{
    public:
        void addFunction(FunctionT function)
        {
            if(function)
                functions_.push_back(function);
        }
 
        void invoke(Object* sender)
        {
            for(size_t i=0; i<functions_.size(); ++i)
                 functions_[i](sender);
        }
 
    private:
        std::vector<FunctionT> functions_;
};
 
class Button: public Object
{
    public:
 
        virtual std::string className(){ return "Button"; };
 
        void addOnPress(Function f)
        {
            event_.addFunction(f);
        }
 
        void press()
        {
             event_.invoke(this);
        }
 
    private:
        Event<Function> event_;
};
 
int main()
{
    Button button;
 
    button.addOnPress(f1);
    button.addOnPress(f2);
 
    button.press();
 
    getchar();
    return 0;
}
0
21.06.2014, 01:48
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.06.2014, 01:48
Привет! Вот еще темы с ответами:

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

Друзья, подскажите, говорят, что можно поля класса инициализировать в момент объявления класса. Как это сделать? - C++
Скажу сразу, а то сейчас начнется, что я прекрасно понимаю, что поля класса при объявлении инициализировать нельзя. Можно конструктором при...

Private и public члены класса - C++
Привет! Есть такой класс: class CDateTime{ private: qint16 year_; qint8 month_, day_; qint8 hours_, minutes_,...

Получение списка public свойств класса - C++
Имеется набор различных классов с различными количествами публичных текстовых свойств. Мне нужно эти поля редактировать. Как получить...


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

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

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