Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在常量和非常量上下文中使用相同的POD?_C++_Constants - Fatal编程技术网

C++ 如何在常量和非常量上下文中使用相同的POD?

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

最初的问题是,我有一些数据要从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 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拥有指针。在这种情况下,数据只引用指针而不获取所有权,只有在读取数据的情况下,它才成为所有者。这是(所有权)的一部分问题。是的,这是真的,我应该对此进行详细阐述。但是,如果结构还包含更大的数据类型,如矩阵或图像,我们不想在其中创建不必要的副本,该怎么办?