制作对象,用va_list构造构造函数

making objects, constructor with va_list

本文关键字:list 构造函数 va 作对 对象      更新时间:2023-10-16

我对va_list有问题。我在构造函数中使用了它来向我的对象获取意外数量的数据。问题代码就在那里:

#include <cstdarg>
#include <iostream>
using namespace std;
class DATA{
private:
int length;
int* tab;
public:
DATA():tab(NULL), length(0){};
DATA(int x, ...):length(x+1){
va_list ap;
va_start(ap, x);
tab=new int[length];
for(int i=0; i<length; ++i){
tab[i]=va_arg(ap, int);
}
va_end(ap);
}
void showthem()const{
if(tab!=NULL){
int x;
for(x=0; x<length-1; ++x){
cout<<tab[x]<<", ";
}
cout<<tab[x];
}
}
}
ostream & operator<<(ostream & out, const DATA & x){
x.showthem();
return out;
}
int main(){
int table [] = {5,1,2,3,4,5,6};
DATA x1(*table);
DATA x2(4,1,2,3,4,5);
cout << x1 << endl;
cout << x2 << endl;
}

当我通过编写所有参数来自然地生成对象时,这是可以的,但当我试图通过表来生成它时,这就成了问题。我在类选项卡中得到了意外的数据。

我想我做错了什么。顺便说一句,我甚至可以通过*table制作这样的对象吗?我给构造函数一些整数,所以它应该可以工作。。。

KIIV做到了。std::initializer_list(此处链接的文档)正是OP所需要的。

忘记变量参数列表。它们允许以几种不同的方式调试难以调试的程序。例如,

DATA x2(41,2,3,4,5)

哇!错过了一个逗号,将在堆栈上读取waaaaay超出范围!或

DATA x2(5, 1,2,3,4,"I am the very model of a modern major-general...")

这将更容易发现,但仍然可以编译,因为编译器不知道或不在乎变元函数允许什么类型。

但是initializer_list<int>只允许int秒,而不必指定int秒的数量。这就少了一个潜在的错误!

修复了一些明显的错误步骤,暂时忽略了房间里的大象std::vector,我们得到了看起来像的东西

#include <initializer_list>
#include <iostream>
class DATA{
private:
int length;
int* tab;
public:
DATA(std::initializer_list<int> vals):
length(vals.size()), tab(new int[length])
{
int index = 0;
for(int val: vals){
tab[index]=val;
index++;
}
}
DATA(const DATA& src) = delete;
DATA& operator=(const DATA& src) = delete;
friend std::ostream & operator<<(std::ostream & out, const DATA & x){
if(x.tab!=NULL){
int index=0;
out<<x.tab[index];
for(index++; index < x.length; ++index){
out<<", "<<x.tab[index];
}
}
return out;
}
};
int main(){
DATA x1({1,2,3,4,5});
std::cout << x1 << std::endl;
}

注意DATA x1({1,2,3,4,5});中的{}大括号。这将建立列表。列表知道它有多大,所以你不必告诉函数有多少项目要来。

请注意,我已经删除了复制构造函数和赋值运算符。这是因为"三条规则"。什么是"三条规则"?阅读链接并找出答案。它将为您节省大量将来的调试工作。

这也非常容易模板化:

template <class TYPE>
class DATA{
private:
int length;
TYPE* tab;
public:
DATA(std::initializer_list<TYPE> vals):
length(vals.size()), tab(new TYPE[length])
{
int index = 0;
for(const TYPE& val: vals){
tab[index]=val;
index++;
}
}
DATA(const DATA& src) = delete;
DATA& operator=(const DATA& src) = delete;
friend std::ostream & operator<<(std::ostream & out, const DATA & x){
if(x.tab!=NULL){
int index=0;
out<<x.tab[index];
for(index++; index < x.length; ++index){
out<<", "<<x.tab[index];
}
}
return out;
}
};
int main(){
DATA<int> x1({1,2,3,4,5});
DATA<std::string> x2({"I", "am", "the", "very", "model", "of", "a", "modern", "major-general"});
std::cout << x1 << std::endl;
std::cout << x2 << std::endl;
}