powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / "property" в C++, и не только C++ Builder
12 сообщений из 12, страница 1 из 1
"property" в C++, и не только C++ Builder
    #34573163
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привет!

Позавчера в одном топике выложил свою разработку 2002 года, возможно, окажется полезной для кого-нибудь.
Это поддержка "property в C++. Конечно, реализуемая не средствами языка.
(вообще не знаю, нужно ли это хоть кому-нибудь, но для меня, пересевшего тогда в 2002 на Visual C с Delphi/C Builder отсутствие свойств у классов казалось неудобством.

Итак, для начала, пример использования
Код: plaintext
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>
#pragma hdrstop

#include "property.h"
//---------------------------------------------------------------------------

class CConsoleWnd
{
private:
    void setCaption(char* NewCaption);
    char* getCaption();
public:
    __property_rw<char*,CConsoleWnd> Caption; // свойство

    CConsoleWnd()
    {
       //определяем, какие функции будут отвечать за реализацию чтения/записи свойства
       Caption.Assign(this, getCaption,setCaption); // Linking
    }
};
//''''''''''''''''''''''''''''''''''
void CConsoleWnd::setCaption(char* NewCaption)
{
   SetConsoleTitle(NewCaption);
}
//''''''''''''''''''''''''''''''''''
//эту функцию не проверял
char* CConsoleWnd::getCaption()
{
   char Buf[ 255 ];
   GetConsoleTitle(Buf, 255 );
   return Buf;
}
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
   CConsoleWnd MyWin;
   MyWin.Caption = "Hallo, my name is Simon";
   printf(MyWin.Caption); //эту строчку не проверял
   return  0 ;
}

желтым показал, собственно, использование свойств


а теперь реализация шаблонов для свойств
Код: plaintext
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.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
// property.h

// PROPERTY-Interface (like VB,Delphi,C++Builder)
// FOR : MS Visual C++

// Copyright by Simon Kroik (2002)

#ifndef _PROPERTY_H__SimonKroik_
#define _PROPERTY_H__SimonKroik_
//--------------------------------------------------------------------
#ifdef _DEBUG
#include <stdio.h>
#include <windows.h>
#include <typeinfo.h>
#endif

void PropertyAssertMsg(char * PropertyName, 
					   const char * _TName, 
					   const char * _ContainerClassName, 
					   bool WasDefined)
{
	#ifdef _DEBUG
		if (!WasDefined)
		{
			char Msg[ 100 ];
			sprintf(Msg,"%s\n\n"
						"There is no function related \n"
						"to property-type : <%s> \n"
						"for class : <%s>.\n",
						PropertyName,_TName,_ContainerClassName);
			MessageBox(NULL,Msg,"Property. Alarm-Message", MB_OK|MB_ICONWARNING );
		}
	#endif
}

//--------------------------------------------------------------------
// Property with "Read-Only" - Interface
template <class _T, class _ContainerClass> class __property_r
{
	typedef _T  (_ContainerClass:: * TGetFunc)(void);
private:
	_ContainerClass* pClient;
    TGetFunc getVal;
	bool HaveLinkedGet;
public:
	__property_r()
	{
		HaveLinkedGet=false;
	}
	//''''''''''''''''''''''''
	void Assign(_ContainerClass *SC,
				TGetFunc get_f)
	{
		pClient=SC;
		getVal=get_f;
		HaveLinkedGet=true;
	}
    //''''''''''''''''''''''''
	operator _T() 
    {
		PropertyAssertMsg("__property_r",
			typeid(_T).name(),
			typeid(_ContainerClass).name(),
			HaveLinkedGet);
        return (pClient->*getVal)();
    }
};
//--------------------------------------------------------------------
// Property with "Write-Only" - Interface
template <class _T, class _ContainerClass> class __property_w
{
	typedef void  (_ContainerClass:: * TSetFunc)(_T);
private:
	_ContainerClass* pClient;
    TSetFunc setVal;
	bool HaveLinkedSet;
public:
	__property_w()
	{
		HaveLinkedSet=false;
	}
	//''''''''''''''''''''''''
	void Assign(_ContainerClass *SC, 
				TSetFunc set_f)
	{
		pClient=SC;
		setVal=set_f;
		HaveLinkedSet=true;
	}
    //''''''''''''''''''''''''
    __property_w<_T,_ContainerClass>& operator = (_T Val)
    {
		PropertyAssertMsg("__property_w",
							typeid(_T).name(),
							typeid(_ContainerClass).name(),
							HaveLinkedSet);
		(pClient->*setVal)(Val); 
        return *this;
    }
};
//--------------------------------------------------------------------
// Property with "Read-Write" - Interface
template <class _T, class _ContainerClass> class __property_rw
{
	typedef _T  (_ContainerClass:: * TGetFunc)(void);
	typedef void  (_ContainerClass:: * TSetFunc)(_T);
private:
	_ContainerClass* pClient;
    TSetFunc setVal;
    TGetFunc getVal;
	bool HaveLinkedGet;
	bool HaveLinkedSet;
public:
	__property_rw()
	{
		HaveLinkedGet=false;
		HaveLinkedSet=false;
	}
	//''''''''''''''''''''''''
	void Assign(_ContainerClass *SC,
				TGetFunc get_f,
				TSetFunc set_f)
	{
		pClient=SC;
		getVal=get_f;
		setVal=set_f;
		HaveLinkedGet=true;
		HaveLinkedSet=true;

	}
	//''''''''''''''''''''''''
	void Assign(_ContainerClass *SC,
				TSetFunc set_f,
				TGetFunc get_f)
	{
		pClient=SC;
		getVal=get_f;
		setVal=set_f;
		HaveLinkedGet=true;
		HaveLinkedSet=true;
	}
	//''''''''''''''''''''''''
	operator _T() 
    {
		PropertyAssertMsg("__property_rw",
							typeid(_T).name(),
							typeid(_ContainerClass).name(),
							HaveLinkedGet);
        return (pClient->*getVal)();
    }
    //''''''''''''''''''''''''
    __property_rw<_T,_ContainerClass>& operator = (_T Val)
    {
		PropertyAssertMsg("__property_rw",
							typeid(_T).name(),
							typeid(_ContainerClass).name(),
							HaveLinkedSet);
		(pClient->*setVal)(Val); 
        return *this;
    }
};
//--------------------------------------------------------------------
#endif
...
Рейтинг: 0 / 0
"property" в C++, и не только C++ Builder
    #34573436
ErV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кроик Семён wrote:

> Привет!
>
> Позавчера в одном топике выложил свою разработку 2002 года, возможно,
> окажется полезной для кого-нибудь. Это поддержка "property в C++. Конечно,
> реализуемая не средствами языка. (вообще не знаю, нужно ли это хоть
> кому-нибудь, но для меня, пересевшего тогда в 2002 на Visual C с Delphi/C
> Builder отсутствие свойств у классов казалось неудобством.

Вообще идея отличная (офигительная, если честно. Сижу и думаю, почему сам не
додумался :)), спасибо :). пара комментов:

Вместо
Код: plaintext
1.
       Caption.Assign(this, getCaption,setCaption); // Linking
Лучше:
Код: plaintext
1.
2.
       Caption.Assign(this, &CConsoleWnd::getCaption,
&CConsoleWnd::setCaption); // Linking
Это для соответствия стандартам C++.

Потом:
Код: plaintext
1.
printf(MyWin.Caption); //эту строчку не проверял
На g++ работает, проверил.

Зато вот это:
Код: plaintext
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.
class CConsoleWnd{
private:
        char buf[ 256 ];
        int i;
    void setCaption(char* NewCaption);
    char* getCaption();
    int getInt();
    void setInt(int newInt);
public:
    __property_rw<char*,CConsoleWnd> Caption; // свойство
    __property_rw<int, CConsoleWnd> Int;

    CConsoleWnd(){
       //определяем, какие функции будут отвечать за реализацию
чтения/записи свойства
       memset(buf, sizeof(buf),  0 );
       Caption.Assign(this, &CConsoleWnd::getCaption,
&CConsoleWnd::setCaption); // Linking
    }
};

void CConsoleWnd::setInt(int newInt){
        i = newInt;
}

int CConsoleWnd::getInt(void){
        return i;
}

int main(int argc, char** argv){
        CConsoleWnd MyWin;
        MyWin.Caption = "Hallo, my name is Simon";
        MyWin.Int =  0 ;
        MyWin.Int++;
        printf(MyWin.Caption); //эту строчку не проверял
        return  0 ;
}
Дает (само собой):
Код: plaintext
1.
2.
3.
4.
5.
property.cpp: In function `int main(int, char**)':
property.cpp:193: error: no `operator++(int)' declared for postfix `++',
trying prefix operator instead
property.cpp:193: error: no match for 'operator++'
in '++MyWin.CConsoleWnd::Int'
Однако это можно обойти (если припрет), или создать типизированные property.

ИМХО, неплохо было бы const модификаторы добавить к аргументам и результатам
get/set функций.

Вообще идея классная :). Если захотеть, можно на этой основе VCL на C++
накатать :) - так как возможности дает очень богатые и основные фишки,
которые мне нужны были от борландовского проперти, на её базе можно
получить. ("Виртуальные" property, индексированные property и т.д. и т.п.).
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
"property" в C++, и не только C++ Builder
    #34573482
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Рад, что идея понравилась.

Я тогда кучу документации перерыл, не мог понять, почему не получается написать перегруженную операцию присваивания для случая, когда свойство стоит справа от знака равно . Пока в одном обсуждении мне, уже отчаявшемуся, не подсказали, что это, на самом деле, cast -оператор.
...
Рейтинг: 0 / 0
"property" в C++, и не только C++ Builder
    #34573565
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PS
если кто будет развивать дальше, то вот мой совет - не стот объединять в один шаблоны
Код: plaintext
1.
2.
__property_r
__property_w
__property_rw
Я это не сделал намеренно , чтобы, например, ошибка присваивания __property_r - свойству(ReadOnly) вылетала НА ЭТАПЕ КОМПИЛЯЦИИ .
...
Рейтинг: 0 / 0
"property" в C++, и не только C++ Builder
    #34576342
_maXmo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
2.
3.
Caption.Assign(this, getCaption,setCaption); // Linking
//не лучше сделать
Caption.Link(this, getCaption,setCaption); //для самодокументируемости?
...
Рейтинг: 0 / 0
"property" в C++, и не только C++ Builder
    #34576395
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
согласен, предложение разумное :)
...
Рейтинг: 0 / 0
"property" в C++, и не только C++ Builder
    #34576477
ErV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_maXmo wrote:

> //не лучше сделать
По-моему это детали, и реализацию каждый сделать волен сам как ему удобно. Главное - идея, а развить её и переделать для себя несложно :)
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
"property" в C++, и не только C++ Builder
    #34576518
f i xit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
зачем вообще оно это все надо? мало ..GetValue(), SetValue(..) ?
вот здесь: http://www.rsdn.ru/article/vcpp/props.xml тоже "дворники к велосипеду" приделывают, если кому интересно ;-)

(2 Кроик: а вообще, молодец, что свой open source выкладываешь, может кто воспользуется. Пиши еще)
...
Рейтинг: 0 / 0
"property" в C++, и не только C++ Builder
    #34576555
ErV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
f i xit wrote:

> зачем вообще оно это все надо?
Потому что property удобней. (IMHO).

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
"property" в C++, и не только C++ Builder
    #34576948
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
f i xit вот здесь : http://www.rsdn.ru/article/vcpp/props.xml тоже "дворники к велосипеду" приделывают, если кому интересно ;-)

Здорово, это ведь та же самая идея , что и у меня была. Спасибо за ссылку.
...
Рейтинг: 0 / 0
"property" в C++, и не только C++ Builder
    #34577066
f i xit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ErV
f i xit wrote:

> зачем вообще оно это все надо?
Потому что property удобней. (IMHO).

Posted via ActualForum NNTP Server 1.4

имхо эффект "удобности" не превышает затрате на "телодвижения" вокруг. ;-)

П.С. из той же статьи (сорри за копи-пасте):


...Однако, описанный метод не лишен недостатков:

- При каждом обращении к "свойству" происходит два вызова функции.
- Использование таких "свойств" требует дополнительных затрат памяти из-за того, что на каждое "свойство" требуется 3 дополнительных указателя, что составляет 12 байт накладных расходов.
- Использование шаблонов приводит к увеличению размеров исполняемого кода, поскольку компилятор будет генерировать отдельный класс для каждой пары "proptype" и "propowner".
- Для каждого "свойства" необходимо не забыть произвести инициализацию в конструкторе класса-владельца.
...
Рейтинг: 0 / 0
"property" в C++, и не только C++ Builder
    #34577436
ErV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
f i xit wrote:

> имхо эффект "удобности" не превышает затрате на "телодвижения" вокруг.
Просто мне модель property кажется более логичное, чем get/set, так как
property явно представляет объект, изменяемый get/set функциями.

ЗЫ. Спорить не буду. Мне property надо - буду юзать. Вам не надо -
не юзайте :).
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / "property" в C++, и не только C++ Builder
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]