powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Константный экземпляр класса. Кто как делает?
25 сообщений из 94, страница 2 из 4
Константный экземпляр класса. Кто как делает?
    #39648590
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv, сделал попроще:
Код: 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.
template <class T = std::nullptr_t> class B;

template <>
class B<std::nullptr_t> : public A
{
  public:

    B()
    {
      printf("B::B()\r\n");
    }

    virtual ~B()
    {
        printf("B::~B()\r\n");
    }
};

template <>
class B<const> : public A
{
  public:

    B()
    {
      printf("const B::B()\r\n");
    }

    virtual ~B()
    {
        printf("const B::~B()\r\n");
    }
};

Объявление:
Код: plaintext
1.
2.
C<> c1;
C<const> c2;


Жаль в C++ нет зарезервированного слова, позволяющего в default подставить <cv-qualifiers type> из объявления lvalue;

Модератор: Будете тут какашками кидаться, выпилю обоих из форума. Не только к тебе относится.
Асанизация проведена.
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39648689
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devВообще, в C++ очень много "недосказанности". К примеру:
* Есть возможность "сказать" new const Type(), но нет возможности этот const хоть как-то "услышать" в реализации перегруженного оператора new, конструктора или деструктора класса;
* Есть возможность переопределить placement new, но компилятор не симулирует его вызов при определении экземпляра объекта на стеке, хотя, такое поведение было бы логичным;
* Можем специализировать шаблоны с дедукцией по параметрам конструктора, но не можем специализировать шаблоны с дедукцией по типу и квалификаторам объявления lvalue;

Просто у тебя в голове какой-то другой свой язык, и ты почему-то его называешь "С++"...
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39648692
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devblonduser, не дождешься!
С дедукцией не получается, а без неё выходит банальный exactly specialized template, который даже школьник напишет.

Ну ты всё же сильно переоцениваешь школьников.
В массе они даже не знают, что такое специализация.
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39648830
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivrdb_devВообще, в C++ очень много "недосказанности". К примеру:
* Есть возможность "сказать" new const Type(), но нет возможности этот const хоть как-то "услышать" в реализации перегруженного оператора new, конструктора или деструктора класса;
* Есть возможность переопределить placement new, но компилятор не симулирует его вызов при определении экземпляра объекта на стеке, хотя, такое поведение было бы логичным;
* Можем специализировать шаблоны с дедукцией по параметрам конструктора, но не можем специализировать шаблоны с дедукцией по типу и квалификаторам объявления lvalue;

Просто у тебя в голове какой-то другой свой язык, и ты почему-то его называешь "С++"...Ты имеешь в виду только последнее замечание или все три?
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39648939
blonduser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне было очень интересно увидеть, как и когда ты будешь освобождать те объекты, которые не удалил в деструкторе когда класс был объявлен как "const"?
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649082
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
blonduserМне было очень интересно увидеть, как и когда ты будешь освобождать те объекты, которые не удалил в деструкторе когда класс был объявлен как "const"?Зачем освобождать то, что не выделяется?
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649307
blonduser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devЗачем освобождать то, что не выделяется?

Это следовало из твоего первого поста и из 21431824 .

Обычно делают конструктор с параметрами и уже в зависимости от них либо создают мембер-объект, либо указателю присваивают NULL .
В деструкторе очищают те объекты указатель которых не NULL и нет необходимости создавать дополнительные ключи и придумывать шаблоны.
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649319
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
blonduserВ деструкторе очищают те объекты указатель которых не NULL и нет необходимости создавать дополнительные ключи и придумывать шаблоны.Хорошо, поясню на пальцах:
допустим, в конструктор передаётся указатель на константную строку из статических ресурсов бинарного модуля и если объект неконстантный, эту строку надо скопировать в кучу и проинициализировать член-указатель на скопированную строку, а если константный, то можно просто проинициализировать указатель на эту константную строку без её копирования. Соответственно, при разрушении неконстантного объекта тебе надо освободить память из под строки, а при разрушении константного объекта этого делать не надо. Так понятнее?
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649335
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devblonduserВ деструкторе очищают те объекты указатель которых не NULL и нет необходимости создавать дополнительные ключи и придумывать шаблоны.Хорошо, поясню на пальцах:
допустим, в конструктор передаётся указатель на константную строку из статических ресурсов бинарного модуля и если объект неконстантный, эту строку надо скопировать в кучу и проинициализировать член-указатель на скопированную строку, а если константный, то можно просто проинициализировать указатель на эту константную строку без её копирования. Соответственно, при разрушении неконстантного объекта тебе надо освободить память из под строки, а при разрушении константного объекта этого делать не надо. Так понятнее?
Код: 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.
// Example program
#include <iostream>
#include <string>
#include <cstring>

class const_C {
    const char *const_string;
    char *nonconst_string;
public:
    const_C(const char* s) {const_string = s; nonconst_string = NULL;}
    const_C(char* s) {const_string = NULL; nonconst_string = strdup(s);}
    void print_state() { if(const_string) std::cout << "i'm a const inited\n"; else if (nonconst_string) std::cout << "i must free a string\n";}
};


const char cstr[] = "hello const";

int main()
{
    char* str = "non const";
    const_C c_obj(cstr);
    const_C obj(str);
    c_obj.print_state();
    obj.print_state();
}


http://cpp.sh/5aj3m

Конструктор понятно как дописать ?
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649343
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devХорошо, поясню на пальцах:
допустим, в конструктор передаётся указатель на константную строку из статических ресурсов бинарного модуля и если объект неконстантный, эту строку надо скопировать в кучу и проинициализировать член-указатель на скопированную строку, а если константный, то можно просто проинициализировать указатель на эту константную строку без её копирования. Соответственно, при разрушении неконстантного объекта тебе надо освободить память из под строки, а при разрушении константного объекта этого делать не надо. Так понятнее?великолепная мина, с отличным, отложенным запалом )) здесь прекрасно всё)))
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649364
blonduser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devдопустим, в конструктор передаётся указатель на константную строку из статических ресурсов бинарного модуля и если объект неконстантный, эту строку надо скопировать в кучу и проинициализировать член-указатель на скопированную строку, а если константный, то можно просто проинициализировать указатель на эту константную строку без её копирования. Соответственно, при разрушении неконстантного объекта тебе надо освободить память из под строки, а при разрушении константного объекта этого делать не надо.

Но ты понимаешь, что указатель можно сделать не константным внутри вызова и изменить строку как угодно?

Именно для строки я видел шаблон в котором реализован механизм который ты описал.
Но там передаются объекты строки, а указатель на строку один.
Если в какой-то момент времени строку надо изменить, то создается копия строки.
При удалении последнего объекта очищается и строка.

Вот такой механизм тебе не подойдет?
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649395
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
blonduserНо ты понимаешь, что указатель можно сделать не константным внутри вызова и изменить строку как угодно?Если член-указатель private, то это реализация только моя. Например:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
struct CTest
{
private:
  char* pStr;

public:
  CTest(const char*);
  CTest& operator = (CTest&&);
  CTest& operator += (CTest&&);
};



blonduserИменно для строки я видел шаблон в котором реализован механизм который ты описал.
Но там передаются объекты строки, а указатель на строку один.
Если в какой-то момент времени строку надо изменить, то создается копия строки.
При удалении последнего объекта очищается и строка.Я уже думал над этим, но так как у меня в структуре не может хранится ничего, кроме одного лишь указателя, придётся сделать static переменную внутри какого-нибудь protected метода, указывающую на экземпляр std::map, который будет дополняться из конструктора (подчищаться из деструктора) и хранить указатели на экземпляры структуры с флагами инициализации, а сам метод будет возвращать состояние инициализации.

Но при любой реализации есть одна загвоздка - при вызове CTest("The test message"), короткая строка может быть передана целиком в кадре стека вместе с указателем на неё и, естественно, может быть затёрта кадрами других вызовов после выхода из области видимости. Или же, может быть передан указатель на строку из кучи, а потом память из под этой строки будет освобождена.
В итоге получается, что при использовании не очень больших строк, накладные расходы на отлов всех этих нюансов перекрывают выгоды от некопирования строки.
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649397
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorychвеликолепная мина, с отличным, отложенным запалом )) здесь прекрасно всё)))А то!
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649400
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Siemargl, указатель внутри структуры, принципиально, только один.
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649423
blonduser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devЯ уже думал над этим, но так как у меня в структуре не может хранится ничего, кроме одного лишь указателя

Ну так одного указателя достаточно.
Ему можно присвоить всё что угодно главное не забывать что присвоил.
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649521
Фотография ну я
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если разнести собсно конструктор и инициализацию, то в принципе можно.
Код: 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.
class C
{
	char* data;
public:
	C()
	{
		// empty constructor, nothing to do in destructor
		data = NULL;
	};
	void init(const char* src)
	{
		// non-const constructor replacer
		printf("non-const %s\n", src);
	};
	void init(const char* src) const
	{
		// const constructor replacer
		printf("const %s\n", src);
	};
	~C()
	{
		if(data)
		{
			// destroy owned data
		}
	};
};
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649541
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devSiemargl, указатель внутри структуры, принципиально, только один.Тогда придется хранить флаг константности инициализации.

Но вообще то проще делать копию в любом случае, если только данных не заоблачное кол-во.
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649562
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще можно использовать constexpr и вынести время жизни объекта вообще на стадию компиляции.
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649753
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devMasterZivпропущено...


Просто у тебя в голове какой-то другой свой язык, и ты почему-то его называешь "С++"...Ты имеешь в виду только последнее замечание или все три?

Все три.
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649775
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devblonduserВ деструкторе очищают те объекты указатель которых не NULL и нет необходимости создавать дополнительные ключи и придумывать шаблоны.Хорошо, поясню на пальцах:
допустим, в конструктор передаётся указатель на константную строку из статических ресурсов бинарного модуля и если объект неконстантный, эту строку надо скопировать в кучу и проинициализировать член-указатель на скопированную строку, а если константный, то можно просто проинициализировать указатель на эту константную строку без её копирования. Соответственно, при разрушении неконстантного объекта тебе надо освободить память из под строки, а при разрушении константного объекта этого делать не надо. Так понятнее?

Твои представления об объектной модели С++ несколько проще, чем она есть на самом деле.
Помимо константных и неконстантных объектов есть ещё объекты временные, и семантика перемещения, которая работает и с константными, и с неконстантными, и с временными объектами.

Тебе надо ОТДЕЛЬНО, ОРТОГОНАЛЬНО К КОНСТАНТНОСТИ ОБЪЕКТА реализовать эту фичу:
твой объект должен хранить либо ссылку на константу либо реальное значение, и знать, на что он ссылается в данный момент.

если объект ссылается на константную строку из стат. ресурсов, то работать с ней пока объект не меняется в этом аспекте.

если эта строка меняется внутри данного объекта, то менять её на ссылку на константные ресурсы либо на реальное значение.

при удалении освобождать что-то только если мы храним реальное значение.

И сделать это, кажется, достаточно просто, нужно хранить внутри

std::variant< std::string, std::string_view >

Я не знаю всю твою семантику, но похоже, что тебе это подойдёт, при этом не нужно делать почти вообще ничего.
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649794
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivВсе три.Давай по пунктам?

* Есть возможность "сказать" new const Type(), но нет возможности этот const хоть как-то "услышать" в реализации перегруженного оператора new, конструктора или деструктора класса;

Зачем возможность писать const, если при создании экземпляра класса в куче этот const, ровным счётом, ни на что не влияет?

* Есть возможность переопределить placement new, но компилятор не симулирует его вызов при определении экземпляра объекта на стеке, хотя, такое поведение было бы логичным;

При размещении экземпляра класса на стеке компилятор сам выделяет память на стеке и инициализирует там экземпляр класса, что примерно равносильно:
Код: plaintext
1.
2.
MyClass* p = (MyClass*)alloca(sizeof(MyClass));
if (NULL != p) new(p) MyClass();

Так почему бы компилятору не создавать placement new по умолчанию, если он не переопределен и не симулировать его вызов? Получили бы более управляемое поведение.

* Можем специализировать шаблоны с дедукцией по параметрам конструктора, но не можем специализировать шаблоны с дедукцией по типу и квалификаторам объявления lvalue;

Есть же using, которые используются подобно typedef! Так почему бы не предусмотреть в них использование cv-квалификаторов c помощью какой-нибудь подходящей семантики? Что-то типа:
Код: plaintext
1.
2.
using MyClassWrapper = MyClass<>;
using const MyClassWrapper = const MyClass<const>;
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649798
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivТвои представления об объектной модели С++ несколько проще, чем она есть на самом деле.
Помимо константных и неконстантных объектов есть ещё объекты временные, и семантика перемещения, которая работает и с константными, и с неконстантными, и с временными объектами.

Тебе надо ОТДЕЛЬНО, ОРТОГОНАЛЬНО К КОНСТАНТНОСТИ ОБЪЕКТА реализовать эту фичу:
твой объект должен хранить либо ссылку на константу либо реальное значение, и знать, на что он ссылается в данный момент.

если объект ссылается на константную строку из стат. ресурсов, то работать с ней пока объект не меняется в этом аспекте.

если эта строка меняется внутри данного объекта, то менять её на ссылку на константные ресурсы либо на реальное значение.

при удалении освобождать что-то только если мы храним реальное значение.

И сделать это, кажется, достаточно просто, нужно хранить внутри

std::variant< std::string, std::string_view >

Я не знаю всю твою семантику, но похоже, что тебе это подойдёт, при этом не нужно делать почти вообще ничего.
Я, пока что, отказался от мысли реализовать эту бредовую идею прямо сейчас, но для себя решил плясать от обратного - если константное значение находится в памяти модуля процесса и выделенная под него память read-only, то инициализировать без копирования и хранить этот признак в std::map, на который будет указывать статический указатель внутри protected виртуального метода. Просто сейчас лень штудировать MSDN на предмет всех этих плясок вокруг получения информации о страницах памяти модуля, так как сейчас нет крайней необходимости работы с большими строками или блобами.
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649808
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devПри размещении экземпляра класса на стеке компилятор сам выделяет память на стеке и инициализирует там экземпляр класса, что примерно равносильно :
Код: plaintext
1.
2.
MyClass* p = (MyClass*)alloca(sizeof(MyClass));
if (NULL != p) new(p) MyClass();



Спасибо, поржал
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649823
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZСпасибо, поржал На , еще поржи! :)
...
Рейтинг: 0 / 0
Константный экземпляр класса. Кто как делает?
    #39649863
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZrdb_devПри размещении экземпляра класса на стеке компилятор сам выделяет память на стеке и инициализирует там экземпляр класса, что примерно равносильно ...
Спасибо, поржал Или ты мне хочешь рассказать, как компилятор вставляет машинный код, оперирующий регистрами (R/E)SP и (R/E)BP? Не стОит!... Ровно тоже самое делает функция _malloca.
...
Рейтинг: 0 / 0
25 сообщений из 94, страница 2 из 4
Форумы / C++ [игнор отключен] [закрыт для гостей] / Константный экземпляр класса. Кто как делает?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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