c++可变参数数
C++ variable number of arguments
我需要定义一个可以接受可变数量的参数的虚拟函数,问题是c风格的省略符不适用于非pod类型,我有有限的内存量(2KB),所以我试图避免分配临时对象只是为了传递给函数,所有参数将是相同的类型(自定义共享指针),我也没有访问stl或boost。是否有c++技巧允许我调用带有变量参数的函数?
假设您的参数类型是类Arg
,您可以尝试:
class ArgUser {
public:
// syntactic sugar:
void method() { // nullary
doMethod();
}
void method( const Arg & a1 ) { // unary
doMethod( &a1 );
}
void method( const Arg & a1, const Arg & a2 ) { // binary
doMethod( &a1, &a2 );
}
// and so on, until max arity
private:
// actual virtual function:
virtual void doMethod( const Arg * a1=0, const Arg * a2=0 /*etc, until max arity */ ) = 0;
};
该解决方案具有以下属性:
- 它使用NVI习惯用法
- 使用指针是因为它们不会导致创建临时变量,即使是未使用的默认参数。
- 在(内联)包装器方法中封装了难看的指针杂耍。
另一种解决方案(可能更有效,也可能不更有效)是:
class AltArgUser {
public:
// syntactic sugar:
void method() { // nullary
doMethod( 0, 0 );
}
void method( const Arg & a1 ) { // unary
doMethod( &&a1, 1 );
}
void method( const Arg & a1, const Arg & a2 ) { // binary
const Arg * args[] = { &a1, &a2 };
doMethod( args, 2 );
}
// and so on, until max arity
private:
// actual virtual function:
virtual void doMethod( const Arg * args[], size_t numArgs ) = 0;
};
要决定使用哪一个,您需要研究在您的特定平台上为每个方法生成的汇编程序。无论选择什么,都应该保留包装器函数。
定义一个函数,接受一个指向形参数组的指针和一个表示数组大小的形参。
同样,如果你不想硬编码一个固定大小的数组,你可以使用alloca
来分配堆栈上的存储空间,而不用担心访问堆或调用free
。
指向共享指针的指针是pod,您可以更改原型以使用每个参数的内存位置吗?像这样(未测试):
shared_ptr arg1;
shared_ptr arg2;
ClassWithVirtualFunction c;
c.yourVirtualFunction(&arg1, &arg2, NULL);
ClassWithVirtualFunction
{
virtual void yourVirtualFunction(shared_ptr* first, ...)
{
va_list marker;
va_start( marker, first );
shared_ptr* current=first;
while (current != NULL)
{
/* do stuff with *current */
current = va_arg( marker, shared_ptr* );
}
va_end(marker);
}
}
您可以使用一个固定数组,它实际上比可变数量的参数更快,占用的空间更少。因为可变数量的参数做了很多检查和安全。
mytype arr[3];
arr[0] = a;
// etc
myfunction(arr, 3);
也许如果你已经有了自己的自定义指针类型,你可以定义自己的基本链表类(毕竟这是c++),最后一个"指向next的指针"为NULL,以表示变量数量的结束
像这样:
class MyPointer
{
// Whatever you have/want
};
class MyArgs
{
static int nargs; // Static class variable for total number of args
MyPointer* data;
MyArgs* next;
public:
MyArgs(int nargs)
{
// Some funky constructor to create required number of args...
}
MyPointer* operator[](int at)
{
// Nice overloaded operator for you to get at data
}
};
class PlanToDoStuff
{
public:
virtual void foobar(MyArgs)=0;
};
class ActuallyDoStuff: public PlanToDoStuff
{
public:
void foobar(MyArgs)
{
// Do stuff with args...
}
};
int main()
{
MyArgs args(3);
ActuallyDoStuff dosomething;
dosomething.foobar(args);
}
相关文章:
- 数数并选择 sqlite 中的前三名
- C++:是否可以编写一个函数,将不同类型的元素附加到变体数组中?
- 通过参考变差函数传递N-D数组
- 数数并说在C++中使用递归
- C++ 通过引用函数传递数组,但内容保持不变
- 具有空构造函数使数组未初始化会使计算速度变慢
- 如何将全局字符变量值分配给数组?
- 我在代码中收到一个运行时错误,该错误如何通过修改最多一个元素来查找数组是否可以变得不减少
- 数独百变需要帮助
- 如何替换QT QML中的变体数组文本
- 字符串的变体数组包含替代空间
- 不同的计数器,同一数组.数组元素不变.C
- 将变参数包中的值加载到临时数组中
- char数组变长会导致意外值
- 排列 +ve 和 -ve 编号的数组,顺序不变
- 如何将小数数组转换为二进制数数组
- 数组元素的值保持不变
- 合并排序变体:使用链接数组
- 传递引用以修改数组之后,为什么它保持不变
- 返回对大小不变的指针数组的引用的最佳方式是什么