nixp.ru v3.0

16 января 2017,
понедельник,
15:50:54 MSK

Аутсорсинг Linux с компанией «Флант»
aspolyakov написал 6 декабря 2007 года в 15:14 (449 просмотров) Ведет себя как мужчина; открыл 2 темы в форуме, оставил 9 комментариев на сайте.

Написал класс, подскажите нужна ли в неи перегрузка = и конструктор копирования, а также покажите на проблемы, если есть) Поясните, если не сложно, когда нужен контор копирования.

#include

class FOpen

{

public:

int fd;

FOpen(char* filename, int mode);

~FOpen(void);

FOpen& FOpen::operator=(const FOpen& rhs);

FOpen(const FOpen& FOpenCCtor );

};

//EOF

#include

#include

#include «fileDescriptor.h»

FOpen::FOpen(char* filename, int mode)

{

fd = open(filename, mode);

}

FOpen::~FOpen(void)

{

if(fd)

{

close(fd);

}

}

FOpen& FOpen::operator=(const FOpen& rhs)

{

if(this == &rhs) return *this;

else

{

fd=rhs.fd;

}

return *this;

}

FOpen::FOpen(const FOpen& FOpenCCtor )

{

fd=FOpenCCtor.fd;

};

//EOF

// Тему переместил(а) Dmitry Shurupov из форума «Помойка программистов».

myst

Лабы только за деньги.

Heavy

>Поясните, если не сложно, когда нужен контор копирования

Читай соответствующую литературу (Шилдт,Страуструп,etc.). Заодно отпадут и другие вопросы.

Code Monkey

ИМХО топик не на месте. для вопросов есть соответствующая ветка.

metal

Топик не в том месте. В данном классе нужна. Почему? А ты попробуй объект своего класса скопировать, первый уничтожить, а второй использовать и если сам написал, поймешь что происходит.

aspolyakov

Попробовал такой test-case:

FOpen * foo;

FOpen * foo1;

foo = new FOpen(«/tmp/start.sh»,O_RDWR);

if(foo->fd == -1)

{

fprintf(stderr,"Open failed:%s (errno=%d)\n»,strerror(errno),errno);

exit(EXIT_FAILURE);

}

foo1=foo;

delete foo;

if(close(foo1->fd) == -1)

{

fprintf(stderr,"close failed — b:%s (errno=%d)\n»,strerror(errno),errno);

exit(EXIT_FAILURE);

}

return 0;

Деструктор первого класса закрыл файл. Как я понял ктор копирования нужен при исп неименованной памяти. Те чтобы избежать ситуации когда создается копия и один из обьектов который ссылается на нее в деструкторе возвращает ее, а др экземпляр еще на нее ссылается. У меня нет дин памяти, но есть идент файла, поэтому я переписал. Что скажите?

#include

class FOpen

{

public:

int fd,mode,en;//en — errno

char * fn;

FOpen( char* filename, int mode );

~FOpen( void );

FOpen& FOpen::operator=( const FOpen& rhs );

FOpen( const FOpen& FOpenCCtor );

private:

void FOpenCtor( char* filename, int mode );

};

//EOF

#include

#include

#include «fileDescriptor.h»

#include

#include

FOpen::FOpen( char* filename, int mode )

{

FOpenCtor( filename, mode );

}

FOpen::~FOpen( void )

{

if(fd)

{

close( fd );

}

delete []fn;

}

FOpen& FOpen::operator = ( const FOpen& rhs )

{

if( this == &rhs ) return *this;

else

{

close(fd);

FOpenCtor( rhs.fn, rhs.mode );

}

return *this;

}

FOpen::FOpen( const FOpen& Sobject )

{

FOpenCtor( Sobject.fn, Sobject.mode );

}

void FOpen::FOpenCtor( char* filename, int tmode )

{

fn = new char[strlen( filename )];

strcpy( fn, filename );

mode = tmode;

fd = open( filename, mode );

if( fd == -1 )

{

en = errno;

}

}

//EOF

metal

Для чего он нужен ты правильно в общем понял, но в данном случае ты его не использовал.



FOpen * foo;
FOpen * foo1;
foo1=foo;

Это у тебя копирование указателей, а не объектов и коструктор копирования не вызывается.И вот это уже абсолютно не корректно:

if(close(foo1->fd) == -1)



fn = new char[strlen( filename )];
 strcpy( fn, filename );

Переполнение буфера.

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

aspolyakov

if(close(foo1->fd) == -1)

Сдесь надо вспомнить про инкапсуляцию? сделать метод

fn = new char[strlen( filename )];

strcpy( fn, filename );

А тут я не могу понять где переполнение, надо использовать 3й параметр strcpy? чтобы при отсутсвии \0 не было прохода по памяти? Верно?

metal
aspolyakov
if(close(foo1->fd) == -1)

Сдесь надо вспомнить про инкапсуляцию? сделать метод

Инкапсуляция у тебя уже есть, fd находится в классе.

Как ты оцениваешь, если кто-то использует твой класс и напишет

foo1->fd = 123;


?

fn = new char[strlen( filename )];

strcpy( fn, filename );

А тут я не могу понять где переполнение, надо использовать 3й параметр strcpy? чтобы при отсутсвии \0 не было прохода по памяти? Верно?

Предположим что filename у тебя абсолютно корректен, в любом случае srtlen найдет 0 или программа завершится аварийно(особо тяжелый случай:)), так что strcpy отработает правильно. Но вот о возвращаемом значении strlen тебе надо прочитать подробнее.

aspolyakov

переполнение будет на один байт?

metal
aspolyakov
переполнение будет на один байт?

ДА

ecobeingecobeing.ru
Экология и вегетарианство на благо всем живым существам Планеты.