Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / вопрос по С++ / 20 сообщений из 20, страница 1 из 1
29.06.2005, 09:24
    #33139518
sanek842
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
изучаю основы C++
написал такой класс , он работает
Код: 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.
//  1 .cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <string.h>
#include <stdlib.h>
#include <iostream.h>

class string {
private:
	char *s;
	int len;
public:
	string() { s = new char[ 1 ]; s[ 0 ]= 0 ; len= 0 ; }
	string(const string& str) : len(str.len) { s = new char[len+ 1 ]; strcpy(s,str.s); }
	string(const char*p) { len=strlen(p); s=new char[len+ 1 ]; strcpy(s,p);}
	~string() { delete [] s; }
	void assign(const string& str);
	string& concat(const string& str);
	void print() const { cout << s << endl; }
};

void string::assign(const string& str)
{
	if ( this == &str ) return; else delete []s;
	len=str.len;
	s = new char[len+ 1 ];
	strcpy(s,str.s);
}

string& string::concat(const string& str)
{	
	int new_l = len + str.len;
	realloc(s,new_l+ 1 );
	memcpy(s+len,str.s,str.len);
	s[len=new_l]= 0 ;
	return (*this);
}


int main(int argc, char* argv[])
{
	char *str="Hello";
	string a(str),b, *p = new string("pointer");

	b.assign("World");
	a.concat(" ").concat(b).print();

	p->print();
	delete p;

	return  0 ;
}


есть 2 вопроса:

1. как бы мне так сделать , чтоб помимо метода assign я мог написать просто
Код: plaintext
1.
2.
3.
..
b="World";
..
?

2. Как тут смотрится ф-ия realloc в методе concat? это я в стиле C сделал, может быть в C++ можно переопределить память покрасивее?
...
Рейтинг: 0 / 0
29.06.2005, 09:42
    #33139555
alex_k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
за realloc нескажу
а вот про первый вопрос типа так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
string& operator=(const char& str)
{
 if ( this == &str ) return *this; else delete []s;
 len=str.len;
 s = new char[len+ 1 ];
 strcpy(s,str.s);
 return *this;
}

...
Рейтинг: 0 / 0
29.06.2005, 10:01
    #33139595
sanek842
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
точно, спасибо
это оказывается называется перегрузка оператора ( до него я еще недошел :)
только пришлось немного подправить

Код: plaintext
1.
2.
3.
4.
	string& operator=(const string& str) 
	{
		if ( this == &str ) return *this; else delete []s;
...

а у вас с char работает ?
...
Рейтинг: 0 / 0
29.06.2005, 10:03
    #33139602
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
alex_k
string& operator=(const char& str)
// должно быть string& operator=(const string& str)
{
здесь можно просто вызвать assign. И сделать сам operator= inline
}


В общем, лучше сам напишу. Выгдядеть должно так :
Код: plaintext
1.
2.
3.
4.
5.
6.
string& operator=(const string& str)
{
  if( this != &str )
    assign(str);
  return *this;
}
...
Рейтинг: 0 / 0
29.06.2005, 10:04
    #33139604
alex_k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
да не :-)
это я опечатался :-)
сначала думал написать char* а потом решил как у тебя assign сделать, вот и сделал что-то среднее :-)
ты, к стати, сделай еще и operator=(const char*)
пригодится :-)


надеюсь это все в образовательных целях?
...
Рейтинг: 0 / 0
29.06.2005, 10:05
    #33139613
alex_k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
2MasterZiv
действительно :-)
...
Рейтинг: 0 / 0
29.06.2005, 10:06
    #33139617
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
В concat тоже хорошо бы проверять if( this != &str ).

realloc применять нельзя здесь - просто будет ошибка.
Либо везде пользуйся new/delete, либо везде malloc/realloc/free.
...
Рейтинг: 0 / 0
29.06.2005, 10:08
    #33139621
anatan1
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
2. Как тут смотрится ф-ия realloc в методе concat? это я в стиле C сделал, может быть в C++ можно переопределить память покрасивее?
Ммм..., а что значит покрасивее. Сначала изучи основы, потом будешь покрасивее писать.
...
Рейтинг: 0 / 0
29.06.2005, 10:18
    #33139646
sanek842
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
alex_kнадеюсь это все в образовательных целях?
пока то да :)
авторrealloc применять нельзя здесь - просто будет ошибка
а ошибка какого плана? просто так то это ведь работает, хотя фиг знает в дейст. оно переопределяет или нет ...
...
Рейтинг: 0 / 0
29.06.2005, 10:21
    #33139651
sanek842
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
alex_kк стати, сделай еще и operator=(const char*)

а это зачем?
присвоение и так идет
...
Рейтинг: 0 / 0
29.06.2005, 11:38
    #33139906
alex_k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
sanek842 alex_kк стати, сделай еще и operator=(const char*)

а это зачем?
присвоение и так идет
я может глупость сморозил, но как будет происходить преобразование
"sometext" который суть char* ?
может я просто недогоняю?
...
Рейтинг: 0 / 0
29.06.2005, 11:55
    #33139981
sanek842
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
честно говоря я тоже недогоняю, но это работает
я с успехом заменил
Код: plaintext
b.assign("World");
на
Код: plaintext
b="World";

мало того , заметь метод concat тоже описан только как
Код: plaintext
string& concat(const string& str);
однако такое
Код: plaintext
1.
a.concat("text");
тоже прокатывает

тоже несовсем понятно :)
( это пример с книжки , просто я его начал модифицировать ... )

to MasterZiv
можно немного пояснить вашу мысль про inline ( что то неуловил :)
...
Рейтинг: 0 / 0
29.06.2005, 12:28
    #33140092
sanek842
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
да , тут еще обнаружилась некорректность с realloc
вот нов. вариант с учетом замечания MasterZiv
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
string& string::concat(const string& str)
{	
	if ( this != &str ) 
	{
		int new_l = len + str.len;
		s=(char*)realloc(s,new_l+ 1 );
		memcpy(s+len,str.s,str.len);
		s[len=new_l]= 0 ;
	}
	return (*this);
}

а почему realloc нельзя исп. в свяке new так и непонятно, может всетаки можно? И чем ( изнутри ) new от malloc отличается?
...
Рейтинг: 0 / 0
29.06.2005, 13:17
    #33140260
Станислав C.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
sanek842а почему realloc нельзя исп. в свяке new так и непонятно, может всетаки можно? И чем ( изнутри ) new от malloc отличается?
Malloc выделяет столько памяти, сколько запросил программист; new - больше . При этом, размер памяти, доступной для записи данных одинаков при использовании данных функций. Просто в блоке памяти, выделяемом по new, присутствует некоторая служебная информация (если не ошибаюсь, длина выделенного блока). Эта служебная информация используется в delete...
А теперь представь, что ты выделил память по new (со служебной информацией), а потом сделал realloc. Таким образом, ты изменил длину выделенного блока не уведомив при этом "службу безопасности". При попытке очистить выделенную память при помощи delete ты рискуешь либо оставить "мусор", либо, что еще хуже, испортить данные...
...
Рейтинг: 0 / 0
29.06.2005, 14:56
    #33140577
sanek842
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
похоже вы правы, почитал еще тут и вцелом по поиску я наверное был неправ :)
наткнулся еще на такую ссылку где говорят что malloc+realloc на базовых типах отруливает быстрее, чем мутить с new , наверное переделаю , new уберу.
...
Рейтинг: 0 / 0
30.06.2005, 00:10
    #33141618
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
sanek842 alex_kк стати, сделай еще и operator=(const char*)

а это зачем?
присвоение и так идет
Если хочешь сделать специфический метод присваивания без создания промежуточного временного объекта.
...
Рейтинг: 0 / 0
30.06.2005, 00:35
    #33141639
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
sanek842>честно говоря я тоже недогоняю, но это работает
я с успехом заменил

Создается компилятором временный объект путем вызова конструктора от строки.

sanek842> можно немного пояснить вашу мысль про inline ( что то неуловил :)

Ну есть такой подход к переопределению операций (один из возможных).
Делать для каждой операции соответствующий метод (например, для = - assign, как у тебя), а потом сами операции делать inline и в них только перевызывать соотв. операцию. В этом случае пользователь имеет возможность использовать как функциональную нотацию, так и операторную.
И нет накладных расходов.
...
Рейтинг: 0 / 0
30.06.2005, 00:44
    #33141648
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
Станислав C. sanek842а почему realloc нельзя исп. в свяке new так и непонятно, может всетаки можно? И чем ( изнутри ) new от malloc отличается?
Malloc выделяет столько памяти, сколько запросил программист; new - больше . При этом, размер памяти, доступной для записи данных одинаков при использовании данных функций. Просто в блоке памяти, выделяемом по new, присутствует некоторая служебная информация (если не ошибаюсь, длина выделенного блока).


Да она и в том блоке, который выделяет malloc, присутствует.
Дело не в этом. Нельзя - потому что нельзя. Потому что

Станислав C.
Эта служебная информация используется в delete...


Станислав C.
А теперь представь, что ты выделил память по new (со служебной информацией), а потом сделал realloc. Таким образом, ты изменил длину выделенного блока не уведомив при этом "службу безопасности". При попытке очистить выделенную память при помощи delete ты рискуешь либо оставить "мусор", либо, что еще хуже, испортить данные...

Ну короче мысли идеологически правильные, но фактически неверные - обычно
в RTTI new/delete используют malloc/free , а вот уже они все разборки с размерами блоков делают. т.е. heap делают один для С++ и С. Но - все равно нельзя. Потому что :
Нельзя по стандарту

Нельзя по сути - ты не знаешь, как работает new, он может быть переопределен и вообще не так работать

В С++ вообще нет перераспределения памяти. Потому что надо вызывать деструкторы и конструкторы.

И, кроме того, это просто не нужно - нужны тебе realloc - используй malloc вместо new.
...
Рейтинг: 0 / 0
19.07.2005, 01:55
    #33172434
_Alexei
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
По поводу

>>естно говоря я тоже недогоняю, но это работает
>>я с успехом заменил
>>b.assign("World");
>>на
>>
>>
>>b="World";

Естественно, что работает
Просто неявно вызывается что-то вроде string(char*const)
т.е.
точно так же, как
string str = "my string";
т.е.
реально
b.assign(string("World"));
b = string("world");

если хочешь запретить - используй "explicit"
...
Рейтинг: 0 / 0
19.07.2005, 09:36
    #33172599
dwl
dwl
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
вопрос по С++
Вообче-то для совместимости c Си все константные "строки" в С++ это char*. За редким исключением.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / вопрос по С++ / 20 сообщений из 20, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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