我创建了一个Date
类,我正在尝试创建一个转换方法,以便您可以将Date
对象转换为const char*
"字符串"。它必须是const char*
,不是 string
。
但是,我发现了一些我无法解决的问题。
这是我的方法:
Date::operator char*() const {
tm date = { 0, 0, 0, day_, month_ - 1, year_ - 1900, 0, 0, -1 };
mktime(&date);
char* weekday[] = { "sunday", ..., "saturday" };
char* month[] = { "january", ..., "diciembre" };
char string[50];
sprintf(string, "%s %d / %s / %d", weekday[fch.tm_wday], day_, month[fch.tm_mon], year_);
return string;
}
编译器说:
warning: address of local variable ‘cadena’ returned [-Wreturn-local-addr]
char string[50];
如果我为字符串变量添加static
标记,它将被共享,我不想要它。
我怎么能这样做?
答案 0 :(得分:2)
在类级别定义缓冲区,并在写入之后从方法返回它。
但请记住,这是一种愚蠢的工作方式,因为(1)对方法的后续调用将改变缓冲区,如果它们仍然保留该指针则会影响以前的调用者,以及(2)因为它违反了单一责任原则 - 最后一次格式化操作的细节在逻辑上根本不属于日期类的状态。此外,必须将缓冲区标记为mutable
,才能使用const
方法进行修改,这清楚地表明您违反了课程的预期职责。
另一方面,"经典C"方法是将方法更改为从调用者接收缓冲区(及其大小),然后写入。这会改变调用者(逻辑上属于逻辑上所属的位置)的内存管理负担,但会使语法使用的方法相当重。
这两种方法在功能上都很笨拙和/或次优;我甚至没有提到返回指向动态分配内存的指针的可能性,因为它具有std::string
的相同开销但没有自动内存管理(所以它绝对是最愚蠢的选择)。
正如其他地方已经说过的那样,正确的C ++方法是返回std::string
,它自己处理已分配内存的生命周期。除非你处于极其特殊的条件下,否则没有理由不使用它。
答案 1 :(得分:1)
您在函数内部创建了一个名为string
的变量,一旦函数返回,它将超出范围(即,无法引用)。你还返回了一个指向它的指针,这意味着你引用了一个不再有效的内存区域。
请考虑返回std::string
,而是为您自动执行内存管理。
编辑:如果不这样做,您可以随时拥有一个static
数组并返回一个指针。
Date::operator const char*() const
{
static char str[50];
// fill in array
return str;
}
当然,您现在无法执行以下操作:
Date d1{...};
Date d2{...};
const char* d1_str = s1;
const char* d2_str = s2;
因为用于将日期转换为字符串的数组由该类的所有实例共享。