我是一名高级 PHP/Perl 开发人员,也是 C++ 的相对初学者。
我拥有的是一个类的对象数组,其中一个元素又是子类的数组指针(如果我使用正确的术语)。我需要的是一个一个地处理主数组并将其元素提取到一个单独的位置,如果它们满足特定条件(唯一的 Name 属性)。然后输出提取一个及其子数组。然后输出原件。
我想出了各种解决方案,并试图在您的帮助下确定哪个是最好的。
细节。
这些是我提到的 2 个类的头文件的一部分:
/// class to define the modificable parameters of the machine
class CMachineParameter {
public:
/// Short name: "Cutoff"
char const *Name;
/// Longer description: "Cutoff Frequency (0-7f)"
char const *Description;
/// recommended >= 0. If negative, minValue is represented as 0 in the pattern
int MinValue;
/// recommended <= 65535. Basically so that it can be represented in the pattern
int MaxValue;
/// flags. (see below)
int Flags;
/// default value for params that have MPF_STATE flag set
int DefValue;
};
///\name CMachineParameter flags
///\{
/// shows a line with no text nor knob
int const MPF_NULL = 0;
/// shows a line with the text in a centered label
int const MPF_LABEL = 1;
/// shows a tweakable knob and text
int const MPF_STATE = 2;
///\}
///\name CFxCallback::CallbackFunc codes
///\{
int const CBID_GET_WINDOW = 0;
///\}
///\name CMachineInfo::HostEvent codes
///\{
/// Sent by the host to ask if this plugin uses the auxiliary column. return true or false.
int const HE_NEEDS_AUX_COLUMN = 0;
///\}
/*////////////////////////////////////////////////////////////////////////*/
/// class defining the machine properties
class CMachineInfo {
public:
CMachineInfo(
short APIVersion, int flags, int numParameters, CMachineParameter const * const * parameters,
char const * name, char const * shortName, char const * author, char const * command, int numCols
) :
APIVersion(APIVersion), PlugVersion(0), Flags(flags), numParameters(numParameters), Parameters(parameters),
Name(name), ShortName(shortName), Author(author), Command(command), numCols(numCols)
{}
CMachineInfo(
short APIVersion, short PlugVersion, int flags, int numParameters, CMachineParameter const * const * parameters,
char const * name, char const * shortName, char const * author, char const * command, int numCols
) :
APIVersion(APIVersion), PlugVersion(PlugVersion), Flags(flags), numParameters(numParameters), Parameters(parameters),
Name(name), ShortName(shortName), Author(author), Command(command), numCols(numCols)
{}
/// API version. Use MI_VERSION
short const APIVersion;
/// plug version. Your machine version. Shown in Hexadecimal.
short const PlugVersion;
/// Machine flags. Defines the type of machine
int const Flags;
/// number of parameters.
int const numParameters;
/// a pointer to an array of pointers to parameter infos
CMachineParameter const * const * const Parameters;
/// "Name of the machine in listing"
char const * const Name;
/// "Name of the machine in machine Display"
char const * const ShortName;
/// "Name of author"
char const * const Author;
/// "Text to show as custom command (see Command method)"
char const * const Command;
/// number of columns to display in the parameters' window
int numCols;
};
这是我的代码:
for(int i(0) ; i < MAX_MACHINES ; ++i) if(song.machine(i)) {
if (song.machine(i)->GetDllName() == "") continue;
Plugin & plug = *((Plugin*)song.machine(i));
const psycle::plugin_interface::CMachineInfo psycle_info = plug.GetInfo();
// Process machine general info: psycle_info.Name, psycle_info.ShortName, psycle_info.Author etc
if(psycle_info.numParameters > 0 && psycle_info.Parameters) {
const int n = psycle_info.numParameters;
for(int i(0) ; i < n; ++i) {
const psycle::plugin_interface::CMachineParameter & psycle_param(*psycle_info.Parameters[i]);
// Process machine's parameters: psycle_param.MinValue, psycle_param.MaxValue, psycle_param.DefValue, psycle_param.Flags etc
基本上,我有一个虚拟机列表,每个虚拟机都有它的参数。只有 ShortName 不同(机器红色 1、机器红色 3、机器灰色 4)。我需要按名称输出唯一的机器及其参数(机器红色,机器灰色)。
在 PHP 中,我会简单地创建和数组,如 $original[psycle_info.Name] = array('author'=>psycle_info.Author, 'parameters'=>array(psycle_param.MinValue, psycle_param.MaxValue, psycle_param.DefValue, psycle_param.标志));
在 C++ 中,我发现我可以使用 std::map 和 std::vector STL 库实现类似的功能。这篇文章展示了一个非常相似的问题以及我从其他来源找到的解决方案: http ://www.dreamincode.net/forums/topic/67804-c-multidimensional-associative-arrays/
但是这样做的一般方法是什么?也许我需要创建 2 个新的非常量元素类?或者可能是一个简单的标准数组并一直使用标准数组循环函数?
非常感谢您的关注!
PS。数据示例:
0.
Name: 'Red Machine v.098'
ShortName: 'Red Machine 1'
Author: 'Jeremy'
Parameters: 0(Name: 'OSC type', MinValue: 0, MaxValue: 255, DefValue:0), 1(Name: 'CutOff', MinValue: 0, MaxValue: 16555, DefValue: 1000), 2(Name: 'LFO', MinValue: 100, MaxValue: 30555, DefValue: 3000)
1.
Name: 'Red Machine v.098'
ShortName: 'Red Machine 2'
Author: 'Jeremy'
Parameters: 0(Name: 'OSC type', MinValue: 0, MaxValue: 255, DefValue:0), 1(Name: 'CutOff', MinValue: 0, MaxValue: 16555, DefValue: 1000), 2(Name: 'LFO', MinValue: 100, MaxValue: 30555, DefValue: 3000)
2.
Name: 'Yellow Machine v.2.4.5'
ShortName: 'Yellow Machine 1'
Author: 'Anthony'
Parameters: 0(Name: 'OSC 1 wave', MinValue: 0, MaxValue: 255, DefValue: 0), 1(Name: 'OSC 2 Wave', MinValue: 0, MaxValue: 255, DefValue: 0), 2(Name: 'OSC 3 Wave', MinValue: 0, MaxValue: 255, DefValue: 0)
3.
Name: 'Yellow Machine v.2.4.5'
ShortName: 'Yellow Machine 2'
Author: 'Anthony'
Parameters: 0(Name: 'OSC 1 wave', MinValue: 0, MaxValue: 255, DefValue: 0), 1(Name: 'OSC 2 Wave', MinValue: 0, MaxValue: 255, DefValue: 0), 2(Name: 'OSC 3 Wave', MinValue: 0, MaxValue: 255, DefValue: 0)
显然,作为这种情况下的输出,我需要有 2 台独特的机器。
PS2。我现在将进一步描述我拥有什么以及需要做什么。
我有一个数组 song.machine(i)
算法:
- 由于 song.machine(i) 信息有限,循环通过它来获取另一个对象并对其进行操作
- 在循环中,从每个 song.machine(i) 创建 Plugin(类对象)插件,以便最终可以通过 psycle_info = plug.GetInfo(); 获取对象 CMachineInfo psycle_info;其中包含我们需要输出的所有信息
- 比较 psycle_info.Name 中的名称。如果已经显示,请跳到下一个。否则,输出数据。
这是我包含的头文件,其中包含我最初显示的 2 个类:http: //sourceforge.net/p/psycle/code/HEAD/tree/trunk/psycle-plugins/src/psycle/plugin_interface.hpp
再次总结一下:由于我只能迭代地访问对象,而且我需要对数据执行一些操作(比如将名称中的所有空格替换为“+”),我想到了创建一个临时数组/类。但可能,创建一个简单的数组 char nameShown[100] 就足够了,我可以在其中存储已经显示的所有名称,并且每次 song.machine(i) 迭代,循环遍历整个 nameShown,如果它包含当前名称,继续下一个。我只是不想每次都循环通过“nameShown”,在 PHP 中我们可以为此使用关联数组:所以我只能检查 ($nameShown[$Name]) 是否存在。就像你说的那样,我也很头疼,我不能复制属性和参数,因为它们是常量!看起来很简单的任务,但对于像我这样的初学者来说太难了。希望我
PS4。我刚刚还更新了主题的名称,因此它将包含“不断”提及。
PS5。这是基本上应该做我需要的代码:
std::string nameShown[100];
bool should_skip = false;
for (int k(0); k < i; k++) {
if (nameShown[k] == psycle_info.Name) {
should_skip = true;
}
}
if(should_skip) continue;
nameShown[i] = psycle_info.Name;
std::ostringstream l; l << "Plugin: " << psycle_info.Name; loggers::warning()(l.str());
所以完整的部分看起来像:
std::string nameShown[100];
for(int i(0) ; i < MAX_MACHINES ; ++i) if(song.machine(i)) {
if (song.machine(i)->GetDllName() == "") continue;
Plugin & plug = *((Plugin*)song.machine(i));
const psycle::plugin_interface::CMachineInfo psycle_info = plug.GetInfo();
// Process machine general info: psycle_info.Name, psycle_info.ShortName, psycle_info.Author etc
bool should_skip = false;
for (int k(0); k < i; k++) {
if (nameShown[k] == psycle_info.Name) {
should_skip = true;
}
}
if(should_skip) continue;
nameShown[i] = psycle_info.Name;
std::ostringstream l; l << "Plugin: " << psycle_info.Name; loggers::warning()(l.str());
if(psycle_info.numParameters > 0 && psycle_info.Parameters) {
const int n = psycle_info.numParameters;
for(int i(0) ; i < n; ++i) {
const psycle::plugin_interface::CMachineParameter & psycle_param(*psycle_info.Parameters[i]);
// Process machine's parameters: psycle_param.MinValue, psycle_param.MaxValue, psycle_param.DefValue, psycle_param.Flags etc
循环插入前的输出:
log: 446322us: W: main: Plugin: Sublime 1.1
log: 446413us: W: main: Plugin: Pooplog FM UltraLight0.68b
log: 446497us: W: main: Plugin: Phantom 1.2
log: 446581us: W: main: Plugin: Pooplog FM UltraLight0.68b
log: 446649us: W: main: Plugin: FeedMe 1.2
log: 446729us: W: main: Plugin: Drum Synth v.2.5
log: 446793us: W: main: Plugin: Sublime 1.1
log: 446876us: W: main: Plugin: Arguru Compressor
log: 446945us: W: main: Plugin: Pooplog Filter 0.06b
log: 447016us: W: main: Plugin: Slicit
log: 447095us: W: main: Plugin: EQ-3
log: 447163us: W: main: Plugin: Arguru Compressor
log: 447231us: W: main: Plugin: Pooplog Filter 0.06b
log: 447294us: W: main: Plugin: Koruz
log: 447361us: W: main: Plugin: Pooplog Filter 0.06b
log: 447425us: W: main: Plugin: EQ-3
log: 447496us: W: main: Plugin: Arguru Compressor
log: 447558us: W: main: Plugin: EQ-3
后:
log: 414242us: W: main: Plugin: Sublime 1.1
log: 414331us: W: main: Plugin: Pooplog FM UltraLight0.68b
log: 414415us: W: main: Plugin: Phantom 1.2
log: 414499us: W: main: Plugin: FeedMe 1.2
log: 414560us: W: main: Plugin: Drum Synth v.2.5
log: 414622us: W: main: Plugin: Arguru Compressor
log: 414694us: W: main: Plugin: Pooplog Filter 0.06b
log: 414761us: W: main: Plugin: Slicit
log: 414830us: W: main: Plugin: EQ-3
log: 414897us: W: main: Plugin: Koruz
请注意,在新添加的循环中,我尝试使用 for (int k(0); k < sizeof(nameShown); k++) 对于 PHP 程序员来说这听起来更明显,但即使是在第一首 song.machine (i) 迭代,它自己循环了很多次,然后给出一个段错误,所以我把它改成了“k < i”。
这基本上就是我所需要的。并且只是好奇它是否是正确的做法,因为每次循环通过过滤器数组的不存在元素对我来说听起来很原始且无效。
另一件事是,在我刚刚完成的独特机器的输出之后,我需要输出整个列表。那又怎样,我必须再次创建整个 song.machine(i) 循环,所以为了避免代码重复,我想到了将我需要的值提取到更简单的数据句柄中。在 PHP 中,我会为此使用关联数组。
再次总结一下,首先我需要输出唯一的机器列表,然后为每个列表设置不同的详细信息。
可能,因为解释起来似乎很复杂(但实际上这是一个非常简单的任务,XML 生成)我会坚持什么是有效的,在这种情况下寻找最好的代码可能太奢侈了。