如何让对象同时当 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; }
};

请问怎么解决?
...全文
547 29 打赏 收藏 转发到动态 举报
写回复
用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)
​ 博主介绍:✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌项目名称基于Web的酒店客房管理系统的设计与实现系统说明3.2.1  用户模块功能分析前台模块应主要包括用户登录模块、用户注册模块、查看客房信息模块、客房预定 模块、用户留言模块、充值模块和个人信息维护模块。用户登录模块:用户通过输入注册的的账号和密码,然后进行身份验证,匹配成功 后实现登录功能。用户注册模块:用户输入合法的账号和密码可以实现注册功能。 查看客房信息模块:用户可以通过首页查看客房的价格,图片,详情等信息,从而   可以选择想要预定的房间。 客房预定模块:用户选择自己想要预定的客房后,可以通过输入相关信息进行订房操作。用户留言模块:用户可以向管理员发送留言。 充值模块:用户可以通过添加银行卡再为自己进行充值操作。 个人信息维护模块:用户可以修改自己的姓名、密码、身份证号等信息,还可以查看自己的订单。3.2.2  管理员模块功能分析对于管理员而言,一个好的管理系统总是能让酒店的管理工作事半功倍[7]。管理员 能够通过这个系统对自己的酒店情况一目了然,应该包括客户留言模块、客房管理模 块、订房信息管理模块、入住信息管理模块、统计分析模块、酒店新闻管理模块、会 员信息管理模块、员工信息管理模块、系统用户管理模块、个人信息维护模块。客户留言模块:管理员可以查看并回复用户的留言。客房管理模块:管理员可以管理客房信息,可以添加新的客房,删除已经停用的客房信息,还可以修改现有的客房信息。订房信息管理模块:管理员可以处理用户的订房请求,为用户办理入住手续。入住信息管理模块:对于没有注册的线下客户,也可以办理入住手续。统计分析模块:可以对酒店所有的入住信息进行记录和总结分析。酒店新闻管理模块:管理员可以更新网站上的新闻公告,展示图片等信息。会员信息管理模块:管理员可以查看到所有的注册会员信息,可以对会员信息进行删除,修改,添加操作。员工信息管理模块:管理员可以查看到自己公司所有的员工信息,而且还可以对员工的相关信息进行管理。系统用户管理模块:管理员可以查看到所有的系统管理员信息并对管理员信息进行管理。个人信息维护模块:管理员可以更改自己的登录密码或者是姓名、性别、手机号等 相关个人信息。​编辑 环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可4.硬件环境:windows 7/8/10 1G内存以上;或者 Mac OS; 5.数据库:MySql 5.7版本;6.是否Maven项目:否;技术栈1. 后端:Spring+SpringMVC+Mybatis2. 前端:JSP+CSS+JavaScript+jQuery使用说明1. 使用Navicat或者其它工具,在mysql中创建对应名称的数据库,并导入项目的sql文件;2. 使用IDEA/Eclipse/MyEclipse导入项目,Eclipse/MyEclipse导入时,若为maven项目请选择maven;若为maven项目,导入成功后请执行maven clean;maven install命令,然后运行;3. 将项目中springmvc-servlet.xml配置文件中的数据库配置改为自己的配置;4. 运行项目,在浏览器中输入http://localhost:8080/ 登录运行截图​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑​编辑 用户管理控制层:package com.houserss.controller;import javax.servlet.http.HttpSession;import org.apache.commons.lang3.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.ResponseBody;import com.houserss.common.Const;import com.houserss.common.Const.Role;import com.houserss.common.ServerResponse;import com.houserss.pojo.User;import com.houserss.service.IUserService;import com.houserss.service.impl.UserServiceImpl;import com.houserss.util.MD5Util;import com.houserss.util.TimeUtils;import com.houserss.vo.DeleteHouseVo;import com.houserss.vo.PageInfoVo;/** * Created by admin */@Controller@RequestMapping(/user/)public class UserController if (ip != null && ip.length() > 0) String[] ips = ip.split(,);for (int i = 0; i  

64,643

社区成员

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

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