【问题标题】:c++ const struct initializationc++ const struct初始化
【发布时间】:2014-08-29 21:00:01
【问题描述】:

我需要用结构字段的有效值初始化这个变量:const WAVEFORMATEX *pFormat

首先我尝试在声明后修改:(*pFormat).wFormatTag = 0; 然后很快发现 const 修饰符不允许这样的操作。然后我尝试了内联初始化的变体

new WAVEFORMATEX() { 0, 0, 0, 0, 0, 0, 0}; //or 
WAVEFORMATEX { 0, 0, 0, 0, 0, 0, 0}; 

第一个抛出一个 'expecting a ;'错误并且第二个初始化表达式没有返回正确的类型。有人可以帮忙吗?我稍后会使用一个函数调用,它必须有一个 const WAVEFORMATEX * 类型的参数。

这是结构文档:http://msdn.microsoft.com/en-us/library/windows/desktop/dd390970(v=vs.85).aspx

【问题讨论】:

  • 如果函数采用const WAVEFORMATEX * 参数,这意味着您必须将WAVEFORMATEX 结构的地址传递给它,并且该函数保证不会更改结构的内容。跨度>
  • 为什么投反对票?由于跛脚的原因,在没有任何 cmets 的情况下投反对票!
  • 我不确定您要解决的真正问题。使用const T* ptr = new T; 并不理想。你不能在这样的指针上使用delete ptr;。你会泄漏内存。
  • 有趣。我想我还有很多研究要做,就 C++ 中的堆内存分配而言。我不知道为什么我不能删除 ptr。我认为如果在使用 new 关键字后不使用 delete,我会泄漏内存。
  • @R_Sahu 看来你可以在const T* 上使用delete

标签: c++ struct constants


【解决方案1】:

函数需要const WAVEWHATEVER* 类型的参数这一事实并不意味着您必须声明此结构以使其同时变为const WAVEWHATEVER*,只需使用:

 void foo(const WAVEWHATEVER* w) {}

 WAVEWHATEVER w;
 w.FormatTag = 0;
 // [...] and so on
 foo(&w);

该功能只保证不会改变你原来w的内容。

【讨论】:

  • 谢谢,我是 C++ 新手。
【解决方案2】:

我认为您正在寻找的是:

const WAVEFORMATEX * pFormat = new WAVEFORMATEX{ 0, 0, 0, 0, 0, 0, 0};

这将允许您在一个表达式中初始化const T*。存在其他方法可以使您的意图在面对变化时更加清晰或稳健,例如创建工厂函数等。

这与您之前尝试的不同之处在于缺少()。使用() 将尝试调用不带参数的默认构造函数,然后当它紧跟初始化列表时会导致语法错误。

不使用new 运算符将导致您在堆栈而不是堆上分配内存,并且您的类型错误,因为结果不是指针。

【讨论】:

  • 其他答案似乎显示了如何以更好的方式使用您正在使用的 API。
  • 为什么你认为另一个答案更好?就可读性而言,这种方式更加简洁。我只需要记住从堆中删除 pFormat。
  • 另一个答案告诉你,也许你实际上并不想要const WAVEFORMATEX *,并且你可以在没有这个限制的情况下实现你的目标。不过,您可以自行决定哪种方法在您的实际应用中最有效。
  • 我的回答解决了对语法的潜在误解。另一个答案解决了对 API 的潜在误解。这两个答案可能对阅读此问题的人有用。
  • @gordlonious: 1. 这个在 C++11 之前的编译器中不起作用,2. 您正在使用必须删除的原始指针,3. 您正在对变量施加约束(没有更多的更改),4. 哪些字段实际定义在哪个位置是不可读的,5. 如果有人通过在您的代码中添加字段来更改结构定义,则工作方式不同
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 2011-07-29
  • 2017-07-21
  • 1970-01-01
  • 2021-09-21
相关资源
最近更新 更多