невозможно объявить класс без инициализации? - PullRequest
7 голосов
/ 01 июля 2011

Для стандартных объектов данных, таких как int, можно сделать следующее

    int number;
    number = 0;

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

Можно ли сделать нечто подобное с пользовательскими классами?

У меня есть класс с именем mem_array с конструктором вида

    mem_array(int,int,std::string);

Я хотел бы сделать следующее

      mem_array myData;
      if(x==0) myData(1,1,"up");
      if(x==1) myData(0,0,"down");

в основном, поэтому я могу использовать myData вне области действия операторов if. Можно ли что-то подобное сделать?

Ответы [ 7 ]

4 голосов
/ 01 июля 2011

Ваша первая строка выдаст вам ошибку, так как конструктор не имеет значений по умолчанию, а конструктор без параметров не существует.

Просто используйте указатель (или, что еще лучше, умный указатель, так что вам не нужно приниматьзабота об удалении объекта).Но убедитесь, что впоследствии проверили, что x было 0 или 1, то есть проверьте, что myData была создана.

mem_array* myData=0;
if(x==0) myData=new mem_array(1,1,"up");
if(x==1) myData=new mem_array(0,0,"down);

assert(myData!=0);
2 голосов
/ 01 июля 2011

добавить конструктор в mem_array, который принимает int

, чтобы вы могли объявить / использовать ...

mem_array myData (x);

внутри этого конструктора,добавьте код инициализации / условия, который вы хотите использовать.

1 голос
/ 01 июля 2011
int number;
number = 0;

Последняя строка явно number = int(0);.Другими словами, используйте тип:

mem_array myData;
if (x == 0) myData = mem_array(1, 1, "up");
if (x == 1) myData = mem_array(0, 0, "down");

Это, к сожалению, требует перегрузки оператора = ():

class mem_array
{
   ...
 public:
  mem_array& operator= (const mem_array& cma);
  {
    /* Copy the information from cma to *this. */

    /* Return a reference to this object. */
    return *this;
  }
};

Альтернативой является использование указателей (динамическое выделение), как и другиерекомендуемые.Это зависит от вас, что вы используете в конце.

1 голос
/ 01 июля 2011

Вы можете использовать указатель:

unique_ptr<mem_array> myData;
switch (x) {
case 0:
    myData.reset(new mem_array(1, 1, "up"));
    break;
case 1:
    myData.reset(new mem_array(0, 0, "down"));;
    break;
}
0 голосов
/ 01 июля 2011

Другое решение заключается в использовании boost::optional<T>. Это делает явным, что ваша переменная может содержать значение not-a-T. Э.Г.

boost::optional<mem_array> myData; // Doesn't hold a mem_array yet.
if(x==0) myData = mem_array(1,1,"up");
if(x==1) myData = mem_array(0,0,"down");
0 голосов
/ 01 июля 2011

Оператор ?: недооценен.

mem_array myData = (x==1) ? myData(1,1,"up") : myData(0,0,"down");
0 голосов
/ 01 июля 2011

Объявление, подобное этому, автоматически вызывает конструктор по умолчанию (т.е. без аргумента или со всеми аргументами имеет значение по умолчанию).Компилятор создаст его автоматически, когда в вашем классе нет конструктора, но поскольку он у вас есть, он не будет создан автоматически.Поэтому объявление не выполняется, поскольку не удается найти конструктор по умолчанию.

...