• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

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

    Запись на курс до 25 апреля. Получить промодоступ ...

Как в конструкторе копирования вызвать метод инициализирующего объекта

  • Автор темы Monarh
  • Дата начала
M

Monarh

Здравствуйте.
Подскажите пожалуйста как, в конструкторе копирования, а также в операторе присваивания, вызвать метод инициализирующего объекта ?
Хотя я думаю сие, как для конструктора копирования так и для оператора присваивания, будет выглядеть одинаково, если ошибаюся поправьте.
Рассмотрим на примере конструктора копирования.
Что делается в программе:
Код:
// Имеется класс
class Cls_Unit_of_Memory
{
...
public:
void Information_About_Array(string&);
Cls_Unit_of_Memory( const Cls_Unit_of_Memory& );
...
};

// Что делается в конструкторе копирования
Cls_Unit_of_Memory::Cls_Unit_of_Memory( const Cls_Unit_of_Memory& ClsObj_Init_Unit_of_Memory )
{
...
string Str_Info;
ClsObj_Init_Unit_of_Memory.Information_About_Array( Str_Info );
...
}

Компилятор ругается:
Код:
CLEAN SUCCESSFUL (total time: 192ms)

mkdir -p build/Debug/Cygwin-Windows/Source
rm -f build/Debug/Cygwin-Windows/Source/Unit_of_Memory.o.d
g++	-c -g -MMD -MP -MF build/Debug/Cygwin-Windows/Source/Unit_of_Memory.o.d -o build/Debug/Cygwin-Windows/Source/Unit_of_Memory.o Source/Unit_of_Memory.cpp
Source/Unit_of_Memory.cpp: In copy constructor `Cls_Unit_of_Memory::Cls_Unit_of_Memory(const Cls_Unit_of_Memory&)':
Source/Unit_of_Memory.cpp:44: error: passing `const Cls_Unit_of_Memory' as `this' argument of `void Cls_Unit_of_Memory::Information_About_Array(std::string&)' discards qualifiers
make: *** [build/Debug/Cygwin-Windows/Source/Unit_of_Memory.o] Error 1
BUILD FAILED (exit value 2, total time: 2s)

Если вызывать функцию( Information_About_Array ) данного объекта, а не инициализирующего, то всё компилится и всё работает,
но в конструкторе копирования необходимо скопировать параметры инициализирующего объекта, а при вызове
метода инициализирующего объекта компилятор сильно ругается, и я не могу понять чего он от меня хочет.

Заранее Всем огромное СПАСИБО.
 
G

grigsoft

Да вроде ясно же написано - объект const, функция нет. Или объявляй Information_About_Array как const (что лучше), или используй const_cast.
 
M

Monarh

Почитал Страуструпа, разобрался !!!
Сделал функцию константной.

Огромное-Преогромное СПАСИБО !!!!!
 
M

Monarh

Но у меня ещё один вопрос:

Сейчас у меня функция Information_About_Array реализована так:
void Information_About_Array( string& Output_String ) const
{
Здесь формируется Output_String
}

Можно ли сделать так:
Объявить функцию Information_About_Array таким образом:
string& Information_About_Array( ) const
{
string Output_String; // Объявить строку локально
Сформировать Output_String;
return Output_String; // Вернуть ссылку на Output_String
}

чтобы использовать её так:

string Str_Info = Information_About_Array( );
или
void New_Function( const string& );
New_Function( Information_About_Array( ) );

Компилятор ругается, что возвращается ссылка на Локальный Объект.

Так действительно делать не стоит, как советует компилятор ?
Или всё-таки ... ???

А-то мне приходится писать так:
string Str_Info;
ClsObj_Init_Unit_of_Memory.Information_About_Array( Str_Info );
New_Function( Str_Info );
вместо
New_Function( Information_About_Array( ) );

Естественно изменять эту строку я не собираюсь, мне нужна она в качестве информативной строки.

Можно конечно объявить функцию Information_About_Array чтобы она возвращала string, а не string& таким образом:
string Information_About_Array( ) const;
но тогда неизвестно вернётся сформированная внутри функции строка или её копия,
и соответственно я не уверен, что при копировании строки она не будет урезана,
поскольку у меня внутри строки могут быть нули '\0' !!!
Может кто-нибудь разъяснит эти моменты ???

Заранее большое спасибо.
 

Kmet

Well-known member
25.05.2006
904
8
BIT
0
правильно советует, время жизни локальной перемнной ограниченно блоком в котором она объявлена, в твоем случае функцией Information_About_Array( )
 
M

Monarh

время жизни локальной перемнной ограниченно блоком в котором она объявлена

Это понятно.
А в случае если возвращается строка ?
Код:
string Information_About_Array() const;

Что тогда происходит в следующем случае:

Код:
Внутри функции сформировалась строка
string Information_About_Array() const
{
string Output_String;
Формируется Output_String;
return Output_String;
}

Функция New_Function принимает в качестве входного параметра строку
void New_Function( const string& );

В функции main осуществляется такая операция:
void main()
{
New_Function( Information_About_Array() );
}

Внутри функции main() создаётся локальная переменная string, которая
инициализируется возвращаемой, из функции Information_About_Array(), строкой
и которая существует до конца блока в котором была создана, в данном случае до конца функции main()
или как ???

Вообще, что происходит в момент
после окончания формирования строки внутри функции Information_About_Array()
и до вызова функции New_Function(...) ???

Какая переменная задействована для передачи строки на вход функции New_Function(...)
и каково время её жизни или место её обитания ?

И если осуществляется инициализация временной строки внутри функции main(), то
как работает конструктор строки инициализированный строкой,
то есть как он копирует входную строку - все String.size() элементов или до первого встречного нуля( '\0' ) ?

По крайней мере конструктор строки инициализированный символьной строкой( char* ) копирует до первого встречного нуля,
ну оно в принципе и понятно, ведь символьная строка( char* ) - это по определению набор символов оканчивающийся нулём,
но у меня внутри строки могут быть и нули и потому копировать до первого нуля мне не надо.

Заранее всем большое спасибо.
 

Kmet

Well-known member
25.05.2006
904
8
BIT
0
Это понятно.
А в случае если возвращается строка ?

string Information_About_Array() const;
вернется временный объект со временем жизни блока, который вызвал функцию.

Какая переменная задействована для передачи строки на вход функции New_Function(...)
и каково время её жизни или место её обитания ?
вернется временный объект со временем жизни New_Function(...)
И если осуществляется инициализация временной строки внутри функции main(), то
как работает конструктор строки инициализированный строкой,
то есть как он копирует входную строку - все String.size() элементов или до первого встречного нуля( '\0' ) ?

По крайней мере конструктор строки инициализированный символьной строкой( char* ) копирует до первого встречного нуля,
ну оно в принципе и понятно, ведь символьная строка( char* ) - это по определению набор символов оканчивающийся нулём,
но у меня внутри строки могут быть и нули и потому копировать до первого нуля мне не надо.

std:string к nullterminated строкам имеет весьма посредственное отношение, которое в принципе ограничивается возможность создание объекта std:string из char*. поэтому рассматривать std:string надо как обычный C++ класс, оюъекты которого копируются путем вызова конструктора копирования
 
M

Monarh

Это понятно.
А в случае если возвращается строка ?

string Information_About_Array() const;
вернется временный объект со временем жизни блока, который вызвал функцию.

Какая переменная задействована для передачи строки на вход функции New_Function(...)
и каково время её жизни или место её обитания ?
вернется временный объект со временем жизни New_Function(...)
Здесь всё стало понятно.
Огромное Спасибо, Kmet.

[quote post='145831' date='18:08:2009, 00:17 ']
Monarh сказал(а):
И если осуществляется инициализация временной строки внутри функции main(), то
как работает конструктор строки инициализированный строкой,
то есть как он копирует входную строку - все String.size() элементов или до первого встречного нуля( '\0' ) ?

По крайней мере конструктор строки инициализированный символьной строкой( char* ) копирует до первого встречного нуля,
ну оно в принципе и понятно, ведь символьная строка( char* ) - это по определению набор символов оканчивающийся нулём,
но у меня внутри строки могут быть и нули и потому копировать до первого нуля мне не надо.
std:string к nullterminated строкам имеет весьма посредственное отношение, которое в принципе ограничивается возможность создание объекта std:string из char*.
поэтому рассматривать std:string надо как обычный C++ класс, оюъекты которого копируются путем вызова конструктора копирования
[/quote]
А здесь не понял.
Что такое "nullterminated строки" ?
И не совсем понял ответ на вопрос: "как работает конструктор строки инициализированный строкой,
то есть как он копирует входную строку - все String.size() элементов или до первого встречного нуля( '\0' ) ?"
или
аналогичный вопрос: "как работает конструктор копирования строки,
то есть как он копирует присваиваемую строку - все String.size() элементов не вдаваясь в подробности содержания строки ?"

Заранее всем большое спасибо.
 
M

Monarh

Понятно, в общем Си-строка.
А по-поводу конструкторов ?
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!