C++ 如何在常量和非常量上下文中使用相同的POD?
最初的问题是,我有一些数据要从plate中保存和检索,并且希望以以下方式使用helper struct:C++ 如何在常量和非常量上下文中使用相同的POD?,c++,constants,C++,Constants,最初的问题是,我有一些数据要从plate中保存和检索,并且希望以以下方式使用helper struct: // this is how I want to use my struct for saving void safeData() { Data data; data.name = getNameToSave(); // returns const char* save(data); } // ... and in the same way for writing. void
// this is how I want to use my struct for saving
void safeData()
{
Data data;
data.name = getNameToSave(); // returns const char*
save(data);
}
// ... and in the same way for writing.
void readData()
{
Data data;
read(data);
use(data);
}
。。。鉴于
struct Data
{
const char* name;
// potentially many more data members
}
我现在绑定到(const)char*而不是std::string,因为这应该与遗留代码一起使用。不幸的是,这将带来一个constness问题:
void read(Data& data)
{
// initial legacy free
free(data.name); // warning: can't convert from const char* to void*
// fill with some data
data.name = getNameFromPlate();
}
所以问题是这样的:因为我的数据检索方法(比如getnamefromwhere)返回const char*我必须使我的结构成员也是const。但是,这与写入用法冲突,因为在这种情况下,它们必须是非常量。解决这个问题的最佳和最干净的方法是什么?最干净的方法是让
数据结构拥有名称数据。因此,当您分配给它时,您应该分配内存并执行memcpy。这是确保a)不泄漏内存b)在使用数据之前不会释放数据,c)同时数据不会被其他进程更改的唯一方法
由于您无论如何都要进行复制,因此使用std::string而不是const char*
可能会使它更易于管理。当您为const char*
赋值时,std::string将为您进行复制,您可以使用c_str()
返回const char*
,这样您仍然可以使用遗留体系结构。您不必进行切换,但从长远来看,这将使其更易于管理。您不仅面临稳定性问题,还面临所有权问题。除非API声明调用方在使用后必须释放getNameToSave()
的返回值,否则应该而不是释放它。当您从文件中读取它时,您必须释放它
因此,更简单的方法是始终使用本地副本,并在使用后持续释放。由于您需要使用旧的constchar*
而不是std::string
,因此最好继续使用好的旧C库函数。这里最好的功能是strdup
,它自动分配内存并将旧字符串复制到内存中
另一种方法是将成员Data::name
的状态存储在布尔成员中:
struct Data
{
const char* name;
bool dyn; // must be freed if true
// potentially many more data members
}
然后,您可以安全地使用:
if (data.dyn && (data.name != nullptr)) {
free(const_cast<char *>(data.name);
}
if(data.dyn&&(data.name!=nullptr)){
免费(const_cast(data.name));
}
你确定getNameToSave
返回一个const char*
你应该free
?如果是这样,你只需要const\u cast
不管你做什么,因为它需要释放
指针。但很可能他们给了你一个指向静态缓冲区的指针,而你不应该实际释放它。不,getNameToSave拥有指针。在这种情况下,数据只引用指针而不获取所有权,只有在读取数据的情况下,它才成为所有者。这是(所有权)的一部分问题。是的,这是真的,我应该对此进行详细阐述。但是,如果结构还包含更大的数据类型,如矩阵或图像,我们不想在其中创建不必要的副本,该怎么办?