如何让对象同时当 const char* 和 const string 使用

ox_thedarkness 2008-03-28 10:41:03
我希望设计一个类txt,作为一个字符串,可以同时这样用:

int main (){

string s1; s1 = txt();
printf( txt() );
try{ throw runtime_error( txt() ); }catch(const exception& e){cout<<e.what();} // 注:希望这里txt自动转为string
cout<< txt() <<endl;

}

一个不成功的设计:
class txt{
std::string str;
public:
txt():str("hello world!\n"){};
operator const char*()const{ return str.c_str(); }
operator const std::string&()const{ return str; }
};

请问怎么解决?
...全文
554 29 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
tongfenglan 2009-10-17
  • 打赏
  • 举报
回复
用于继承
帅得不敢出门 2008-03-30
  • 打赏
  • 举报
回复
string
与char * 类型不一样 虽然都是以null结尾 但是不是等价的 .

如果把两个当成无差别类型 感觉就是把两个相似不相交的点给硬拧起来.

同意说这是 : " 把问题复杂化" 的仁兄.
chao_83 2008-03-30
  • 打赏
  • 举报
回复
的确用处不大,
你看标准库的string都不支持自动转换成const char *;
而是用.c_str()来做啊。
说明自动转换的做法很可能是弊大于利。
ox_thedarkness 2008-03-30
  • 打赏
  • 举报
回复
以前没看过你说的那篇。稍微扫了一下,每个要点都是10+页的E文ppt,太长了没时间看。

不过我觉得这OOP并不适用于这里:我需要的一个过程式语法工具,类似 make_pair 或者 less 那样,而非OOP。

而且,OOP并不适合很多问题。
他的利器之一是运行时多态,处理图形对象绘制,或者游戏单位的行动相当有效,但不是所有过程都需要多态。
利器之二是继承,将通用操作丢到基类中做出一个框架,留出虚函数供给子类接口。但是即使真的有通用操作,过程式复用远比OOP重构容易。最终敲定抽象之前必须经过N次重用洗礼,往往过度设计下还缺接口老是返工。

所以还是比较习惯GP+过程式+Object Based。
ox_thedarkness 2008-03-30
  • 打赏
  • 举报
回复
主要是string类没有虚析构,所以写上这个防被继承
hityct1 2008-03-30
  • 打赏
  • 举报
回复
问20楼:
class txt_lock_inherit 什么用?
ox_thedarkness 2008-03-30
  • 打赏
  • 举报
回复
回楼上的,这不是面向对象的设计。
我习惯把一些常用的东西做成一个小工具库。

界面提示时、或者抛出异常时,格式化一个字符串是很常见的。在java等语言中,自动toString配合字符串连接很好解决了这个问题,而在C++中,我就需要:

CString str;      str.Format( "(%d,%d)", x, y );
SetWindowText( str );

stringstream ss; ss<<"load failed, error:"<< errno;
throw runtime_error( ss.str() );


有了这个小工具之后,我只需要:

SetWindowText( txt( "(%d,%d)", x, y ) );

throw runtime_error( txt("load failed, error:%d", errno ) );


- - 虽然实际上也差不多,不过我对短的代码行数挺执着。
taodm 2008-03-29
  • 打赏
  • 举报
回复
google robert c martin的“面向对象设计的11原则--你称得上OO专家么?”
systemthink 2008-03-29
  • 打赏
  • 举报
回复
不想说话。。。
ox_thedarkness 2008-03-29
  • 打赏
  • 举报
回复
- - 最后公开继承string了,没有放私有变量,并且禁止继承
感觉那个禁止继承不太美观...

附上全部实际代码。感谢大家的回答,尤其是hityct1提出的继承方案。

我希望这个代码在任何合法使用情况下都没有bug。如果没有人指出bug的话,明天结贴。

class txt_lock_inherit{	
friend class txt;
txt_lock_inherit(){};
txt_lock_inherit(const txt_lock_inherit&){};
};

class txt:
public std::string,
private virtual txt_lock_inherit
{
public:
txt(){}
txt(const char* format, ...){
char buf[1024*4];
buf[ sizeof(buf)-1 ] = 0;
va_list arglist;

va_start(arglist, format);
_vsnprintf(buf, sizeof(buf)-1, format, arglist); // VC7,暂时没有处理可移植问题
std::string::assign(buf);
}

operator const char*()const{ return c_str(); }
};
ox_thedarkness 2008-03-28
  • 打赏
  • 举报
回复
hityct1 的做法中,私有继承之后 txt -> string 的自动转换完全堵住了。

类似的做法, txt公有继承自string,看似几乎解决了:

class txt: public string{
public:
txt():string("hello world!\n"){};
operator const char*()const{ return c_str(); }
};


潜在问题是,string 的析构函数不一定是虚的。至少vc7里面不是虚函数。
所以任何将 txt* 丢给 string* 后 delete,前者的析构函数都不会被调用。
paidfighting 2008-03-28
  • 打赏
  • 举报
回复
lz,你的这种要求是做内部类型,内部库的人应该做的,这也不应该是一个外在的class应该有的特性,除非你考虑的特别周全,否则也很难避免别人使用时出问题。
hityct1 2008-03-28
  • 打赏
  • 举报
回复
printf( "%s\n",ConString() ); 出现异常
paidfighting 2008-03-28
  • 打赏
  • 举报
回复
继承不太好,派生类里要是有数据,赋值就有问题了,除非显式的用多态。。。但又何必
hityct1 2008-03-28
  • 打赏
  • 举报
回复
而且printf也不是这么用的啊?
hityct1 2008-03-28
  • 打赏
  • 举报
回复
但是
printf( ConString() ); //当成const char *
为什么成功不明白。

还需要完善。
xkyx_cn 2008-03-28
  • 打赏
  • 举报
回复
mark 学习
hityct1 2008-03-28
  • 打赏
  • 举报
回复

//我觉得私有继承string可以
//
#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;

class ConString: private std::string
{
public:
ConString():string("hello world!\n")
{
}

operator const char*() const
{
return this->c_str();
}

operator const std::string&() const
{
return *this;
}

friend inline std::ostream& operator<<(std::ostream& strm,const ConString& str)
{
strm << str.c_str();
return strm;
}
};


int main (){

string s1;
s1 = string(ConString());
cout<< s1 <<endl;
printf( ConString() ); //当成const char *

try
{
throw runtime_error( ConString() );
}
catch(const exception& e)
{
cout << e.what() <<endl;
}
cout << ConString() <<endl;

//ConString s2;
//s2="new";//不能通过
//s2=string("new");//不能通过

//ConString s3("de");//不能通过

return 0;
}

//但是 s1 = string(ConString());
// 和throw runtime_error( ConString() );
//这两句有警告:
//warning C4243: type cast conversion from 'class ConString *' to 'const class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &' exists, but is inaccessible
//vc6.0
homesos 2008-03-28
  • 打赏
  • 举报
回复
专用写方法返回想要的结果。

不要把简单的事情搞复杂。
ox_thedarkness 2008-03-28
  • 打赏
  • 举报
回复
那个class仅供参考
我的问题是让main中那四行可以同时正确通过。怎么办? 另:最好是不使用任何非标准扩展。
加载更多回复(9)

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧