聪明的char *级...... [英] Smart char * class...

查看:46
本文介绍了聪明的char *级......的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个智能char *类,在所有情况下都像char *,但是

允许你用它做一些std :: string类型的东西。 (请不要说

使用std :: string - 它不是一个选项......)。这是我的尝试,

但它似乎缺乏...我知道strdup()是非标准的

(对C ++来说是一个坏主意)代码) - 请耐心等待:


/ *假设包含相关标题* /


class char_ptr

{

char * value;


public:

char_ptr():value(strdup("") ){}

~char_ptr(){free(value);}

char_ptr(const char * s):value(strdup(s?s:"" )}} {}

void operator =(const char * s){

free(value);

value = strdup (s?s:"");

};


除了忽略strdup()的返回值之外,还有什么

在此定义中调用未定义的行为?如果没有,

以下代码是否有效?


char_ptr s(Hello,world!\ n);

printf("%s",s);


我知道这些东西很奇怪的性质;是否有(更好的)

方式来完成这项任务?它可以完成吗?


-

Christopher Benson-Manica |我*应该*知道我在说什么 - 如果我

ataru(at)cyberspace.org |不,我需要知道。火焰欢迎。

I need a smart char * class, that acts like a char * in all cases, but
lets you do some std::string-type stuff with it. (Please don''t say to
use std::string - it''s not an option...). This is my attempt at it,
but it seems to be lacking... I''m aware that strdup() is nonstandard
(and a bad idea for C++ code) - please just bear with me:

/* Assume relevant headers are included */

class char_ptr
{
char *value;

public:
char_ptr() : value(strdup("")) {}
~char_ptr() {free(value);}
char_ptr( const char *s ) : value(strdup(s?s:"")) {}

void operator= ( const char * s ) {
free( value );
value=strdup( s?s:"" );
};

Aside from ignoring the return value of strdup(), is there anything
that invokes undefined behavior in this definition? If there is not,
should the following code work or not?

char_ptr s( "Hello, world!\n" );
printf( "%s", s );

I''m aware of the very kludgy nature of this stuff; is there a (better)
way to accomplish this task? Can it be done at all?

--
Christopher Benson-Manica | I *should* know what I''m talking about - if I
ataru(at)cyberspace.org | don''t, I need to know. Flames welcome.

推荐答案

Christopher Benson-Manica写道:
Christopher Benson-Manica wrote:
我需要一个聪明的char *类,就像一个char *在所有情况下,但
允许你用它做一些std :: string类型的东西。 (请不要说
使用std :: string - 它不是一个选项......)。


你能否解释为什么它不是一个选项?

这是我的尝试,
但它似乎缺乏...我知道strdup()是非标准的(对C ++代码来说是一个坏主意) - 请耐心等待:

/ *假设包含相关标题* /

类char_ptr
{char * value;

公开:
char_ptr():value(strdup("" )} {}
~char_ptr(){free(value);}
char_ptr(const char * s):value(strdup(s?s:"")){}

void operator =(const char * s){
free(value);
value = strdup(s?s:"");
}; 在此定义中调用未定义的行为?如果没有,
是否应该使用以下代码?

char_ptr s(Hello,world!\ n);
printf("%s" ;,s);


编号将对象传递给具有可变数量参数的函数

未定义。因此,除非你定义一个''char_ptr'',''operator const char *''的成员函数,否则printf不会起作用:


...

运算符const char *()const {返回值; }


..然后你需要做


printf("%s",(const char *)s);


此外,你的班级有缺陷:它缺少一个复制构造函数,根据三条规则你必须拥有b $ b。 />
我知道这些东西很奇怪的性质;是否有(更好的)方法来完成这项任务?它可以完成吗?
I need a smart char * class, that acts like a char * in all cases, but
lets you do some std::string-type stuff with it. (Please don''t say to
use std::string - it''s not an option...).
Could you maybe explain why it''s not an option?
This is my attempt at it,
but it seems to be lacking... I''m aware that strdup() is nonstandard
(and a bad idea for C++ code) - please just bear with me:

/* Assume relevant headers are included */

class char_ptr
{
char *value;

public:
char_ptr() : value(strdup("")) {}
~char_ptr() {free(value);}
char_ptr( const char *s ) : value(strdup(s?s:"")) {}

void operator= ( const char * s ) {
free( value );
value=strdup( s?s:"" );
};

Aside from ignoring the return value of strdup(), is there anything
that invokes undefined behavior in this definition? If there is not,
should the following code work or not?

char_ptr s( "Hello, world!\n" );
printf( "%s", s );
No. Passing an object to a function with variable number of arguments
is undefined. So, printf is not going to work unless you define one
more member function of ''char_ptr'', ''operator const char*'':

...
operator const char* () const { return value; }

.. Then you will need to do

printf("%s", (const char*)s);

Also, your class is defective: it is missing a copy constructor, which
you have to have according to the "Rule of Three".
I''m aware of the very kludgy nature of this stuff; is there a (better)
way to accomplish this task? Can it be done at all?




继续为你的课程添加功能,直到你做对了。然后

看看你不需要哪些功能,然后摆脱它。


Victor



Keep adding functionality to your class until you get it right. Then
see which functionality you don''t need, and get rid of it.

Victor


Victor Bazarov< v。******** @ comacast.net>这样说:
Victor Bazarov <v.********@comacast.net> spoke thus:
你能否解释为什么它不是一个选择?


我的老板不喜欢他们,并且所有代码都需要char *',而且没有

它会捕获std :: exception,所以...

否。将对象传递给具有可变数量参数的函数
是未定义的。所以,除非你定义一个''char_ptr'',''operator const char *''的更多成员函数,否则printf不会起作用:


啊,那个这就是我想要的! :)

此外,你的班级有缺陷:它缺少一个复制构造函数,根据三条规则你必须拥有它。


这也是*我想要的,非常好!

继续为你的课程添加功能,直到你做对了。然后
看看你不需要哪些功能,并摆脱它。
Could you maybe explain why it''s not an option?
My boss doesn''t like them, and all the code expects char *''s, and none
of it catches std::exception, so...
No. Passing an object to a function with variable number of arguments
is undefined. So, printf is not going to work unless you define one
more member function of ''char_ptr'', ''operator const char*'':
Ah, that''s what I wanted! :)
Also, your class is defective: it is missing a copy constructor, which
you have to have according to the "Rule of Three".
That was *also* what I wanted, excellent!
Keep adding functionality to your class until you get it right. Then
see which functionality you don''t need, and get rid of it.




会的,谢谢!


-

Christopher Benson-Manica |我*应该*知道我在说什么 - 如果我

ataru(at)cyberspace.org |不,我需要知道。火焰欢迎。



Will do, thanks!

--
Christopher Benson-Manica | I *should* know what I''m talking about - if I
ataru(at)cyberspace.org | don''t, I need to know. Flames welcome.


Christopher Benson-Manica写道:
Christopher Benson-Manica wrote:
我需要一个聪明的char *类,就像一个char *在所有情况下,但
允许你用它做一些std :: string类型的东西。 (请不要说
使用std :: string - 它不是一个选项......)。


为什么?我真的很想知道。

这是我的尝试,
但似乎缺乏...我知道strdup()是非标准的
(对C ++代码一个坏主意) - 请耐心等待:

/ *假设包含相关标题* /

class char_ptr
{
char * value;

public:
char_ptr():value(strdup("")){}
~char_ptr(){free(value); } char_ptr(const char * s):value(strdup(s?s:"")){}

void operator =(const char * s){
free(value);
value = strdup(s?s:"");
};


我没有看到未定义的行为,但是我确实看到赋值运算符

很容易自毁你的字符串


char_ptr x;

...

x = x; //< - 砰。 (这可能会以不太明显的形式出现。)


除了忽略strdup()的返回值之外,还有什么能够在此定义中调用未定义的行为吗?如果没有,
是否应该使用以下代码?

char_ptr s(Hello,world!\ n);
printf("%s" ;,s);

我知道这些东西非常笨拙;是否有(更好的)方法来完成这项任务?它可以完成吗?
I need a smart char * class, that acts like a char * in all cases, but
lets you do some std::string-type stuff with it. (Please don''t say to
use std::string - it''s not an option...).
Why? I would really like to know.
This is my attempt at it,
but it seems to be lacking... I''m aware that strdup() is nonstandard
(and a bad idea for C++ code) - please just bear with me:

/* Assume relevant headers are included */

class char_ptr
{
char *value;

public:
char_ptr() : value(strdup("")) {}
~char_ptr() {free(value);}
char_ptr( const char *s ) : value(strdup(s?s:"")) {}

void operator= ( const char * s ) {
free( value );
value=strdup( s?s:"" );
};

I do not see undefined behaviour, but I do see that the assignment operator
is prone to self-destruct your string in

char_ptr x;
...
x = x; // <- bang. (This can occur in less abvious forms.)

Aside from ignoring the return value of strdup(), is there anything
that invokes undefined behavior in this definition? If there is not,
should the following code work or not?

char_ptr s( "Hello, world!\n" );
printf( "%s", s );

I''m aware of the very kludgy nature of this stuff; is there a (better)
way to accomplish this task? Can it be done at all?




现在,如果这样可行,那么原因就是编译器没有做任何类型检查

这里。我做了一个测试:


#include< string.h>

#include< stdlib.h>


class char_ptr

{

char * value;


public:

char_ptr( ):value(strdup("")){}

~char_ptr(){free(value);}

char_ptr(const char * s):value (strdup(s?s:"")){}


void operator =(const char * s){

free(value);

value = strdup(s?s:"");

}

};


int main(void){

char_ptr s(" Hello,world!\ n");

printf("%s",s) ;

}

这个编译在g ++ - 3.4.0 / Linux但是段错误。你需要演员:


#include< stdio.h>

#include< string.h>

#包括< stdlib.h>


class char_ptr

{

char * value;


public:

char_ptr():value(strdup("")){}

~char_ptr(){free(value);}

char_ptr(const char * s):value(strdup(s?s:"")){}


void operator =(const char * s){

免费(价值);

value = strdup(s?s:"");

}


运算符const char *(void)const {

返回值;

}

};


int main(void){

char_ptr s(Hello,world!\ n);

printf(" ;%s",(const char *)s);

}


这似乎有效,但如上所述存在缺陷。

现在,如果你还需要演员,为什么不使用std :: string?

Best


Kai-Uwe Bux

ps:如果你真的坚持,这是我很久以前写的版本

说服自己,我不能比std :: string做得更好。

#include< string>


class

minimal_string {

private:


char * data;

std :: size_t size;


inline

void allocate(size_t __size ){

size = __size;

data = new char [__size];

}


inline

void deallocate(void){

delete [] data;

}


inline

static

void memcopy(const char * source,char * dest,size_t size){

std :: char_traits< char>: :copy(dest,source,size);

}


inline

void copy_string(const char * str){

//警告:[没有解除分配]

/ *

|这在构造函数中使用。因此,

|不能解除分配。

* /

if(str!= NULL){

std :: size_t l(std :: char_traits< ; char> :: length(str)+ 1);

allocate(l);

memcopy(str,data,l);

} else {

//也许,我们应该抛出一些东西?

allocate(1);

* data = 0;

}

}


public:


minimal_string(void){

分配(1);

*数据= 0;

}


minimal_string(const char * str) {

copy_string(str);

}


minimal_string(const minimal_string& other){

std :: size_t l(other.length());

allocate(l);

memcopy(other.data,data,l);

}


~minimal_string(void){

删除[]数据;

}


const minimal_string& operator =(const minimal_string& other){

if(this!=& other){

deallocate();

std: :size_t l(other.length());

allocate(l);

memcopy(other.data,data,l);

}

返回(* this);

}


void setString(const char * str){

deallocate();

copy_string(str);

}


std :: size_t length(void) const {

return(size);

// return(1 + std :: char_traits< char> :: length(data));

}


运算符const char *(void)const {

return(data);

}


}; // minimal_string

注意,在我对异常安全编码有所了解之前,我写了这个。

因此,当某些事情发生时很可能会泄漏内存

抛出。



Now, if this works then the reason would be that the compiler does not do
any type checking here. I ran a test:

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

class char_ptr
{
char *value;

public:
char_ptr() : value(strdup("")) {}
~char_ptr() {free(value);}
char_ptr( const char *s ) : value(strdup(s?s:"")) {}

void operator= ( const char * s ) {
free( value );
value=strdup( s?s:"" );
}
};

int main ( void ) {
char_ptr s( "Hello, world!\n" );
printf( "%s", s );
}
This compiles on g++-3.4.0/Linux but segfaults. You need a cast:

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

class char_ptr
{
char *value;

public:
char_ptr() : value(strdup("")) {}
~char_ptr() {free(value);}
char_ptr( const char *s ) : value(strdup(s?s:"")) {}

void operator= ( const char * s ) {
free( value );
value=strdup( s?s:"" );
}

operator const char * ( void ) const {
return value;
}
};

int main ( void ) {
char_ptr s( "Hello, world!\n" );
printf( "%s", (const char*)s );
}

This seems to work, but is flawed as pointed out above.
Now, if you need a cast anyway, why not use std::string?
Best

Kai-Uwe Bux

ps.: If you really insist, here is a version that I wrote long ago to
convince myself that I cannot do better than std::string.
#include <string>

class
minimal_string {
private:

char* data;
std::size_t size;

inline
void allocate ( size_t __size ) {
size = __size;
data = new char [ __size ];
}

inline
void deallocate ( void ) {
delete[] data;
}

inline
static
void memcopy ( const char* source, char* dest, size_t size ) {
std::char_traits<char>::copy( dest, source, size );
}

inline
void copy_string ( const char* str ) {
// WARNING: [no deallocation]
/*
| This is used in the constructor. Therefore,
| no deallocation can be done.
*/
if ( str != NULL ) {
std::size_t l ( std::char_traits<char>::length( str ) + 1 );
allocate( l );
memcopy( str, data, l );
} else {
// maybe, we should throw something ?
allocate( 1 );
*data = 0;
}
}

public:

minimal_string ( void ) {
allocate( 1 );
*data = 0;
}

minimal_string ( const char* str ) {
copy_string( str );
}

minimal_string ( const minimal_string & other ) {
std::size_t l ( other.length() );
allocate( l );
memcopy( other.data, data, l );
}

~minimal_string ( void ) {
delete [] data ;
}

const minimal_string & operator= ( const minimal_string & other ) {
if ( this != &other ) {
deallocate();
std::size_t l ( other.length() );
allocate( l );
memcopy( other.data, data, l );
}
return( *this);
}

void setString ( const char* str ) {
deallocate();
copy_string( str );
}

std::size_t length ( void ) const {
return( size );
//return( 1 + std::char_traits<char>::length( data ) );
}

operator const char* ( void ) const {
return( data );
}

}; // minimal_string
Beware, I wrote this before I knew anything about exception safe coding.
Therefore, it is very likely that this leaks memory when something is
thrown.


这篇关于聪明的char *级......的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆