2016-06-03 2 views
-1

У меня проблема с va_list. Я использовал его в конструкторе, чтобы получить неожиданный объем данных для моего объекта. Проблемный код есть:создание объектов, конструктор с 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; 
} 

Когда я сделать объект естественным путем записи всех параметров, это нормально, но когда я пытаюсь сделать это с помощью таблицы, что делает проблему. Я получил неожиданные данные на вкладке класса.

Я думаю, что я делаю что-то неправильно. В forst way - могу ли я сделать такой объект через * таблицу? Я даю конструктору некоторое количество целых чисел, поэтому он должен работать ...

+1

Я голосую, чтобы закрыть этот вопрос не по теме, потому что этот вопрос не имеет смысла. – SergeyA

+4

Прежде всего, вариативные функции не должны использоваться в C++. Во-вторых, самореализованные динамические массивы не должны использоваться в C++. В-третьих, если вы настроены на использование вариационных функций, вам нужно научиться этому. Прямо сейчас ваш код не имеет смысла. – SergeyA

+0

'DATA x1 (* table)' будет 'DATA x1 (5)' ... – Jarod42

ответ

1

KIIV прибил его. std::initializer_list (documentation linked here) - это именно то, что требуется OP.

Забудьте о списках переменных аргументов. Они позволяют трудно отлаживать программы несколькими способами. Например,

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

Упс! Пропустил запятую и собираюсь прочитать waaaaaay вне диапазона на стеке! Или

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

Что было бы намного легче обнаружить, но по-прежнему собирает, потому что компилятор не знает, или все равно, что напечатает varadic функция позволяет.

Но initializer_list<int> разрешает только int с, и вам не нужно указывать число int s. Еще одна потенциальная ошибка!

подправить некоторые из очевидных неправильных шагов и игнорируя elephant in the room, 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}); Это устанавливает перечень. Список знает, насколько он велик, поэтому вам не нужно BLEEP, рассказывая функции, сколько предметов идет.

Обратите внимание, что я удалил конструктор копирования и оператор присваивания. Это из-за правила трех. What is The Rule of Three? Прочтите ссылку и узнайте. Это сэкономит вам много будущей отладки.

Это также смехотворно легко шаблона:

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; 
} 
Смежные вопросы