Помощь с указателями, указателями на объекты и классами - PullRequest
0 голосов
/ 14 ноября 2010

Я смотрю в правильном направлении. У меня 1 класс Event

class Event{
private:
 vector<string> Question;
 char Mode;// 1 = Ascending 2 = Descending 3 = None
 string EventName;
public:
    Event(string Name){
        EventName = Name;
        SetQuestionSize();
        SetQuestion();
        Mode = 3; 
    }

    void SetName(string NewName){
        EventName = NewName;
    }
    void SetQuestionSize(){
        Question.resize(15);
    }

    int ReturnQuestionSize(){
        return Question.size();
    }

    void SetQuestion(){
        Question[0]="Enter ";
        Question[1]="1 ";
        Question[2]="to ";
        Question[3]="sort ";
        Question[4]="in ";
        Question[5]="ascending ";
        Question[6]="order, ";
        Question[7]="2 ";
        Question[8]="for ";
        Question[9]="Descending, ";
        Question[10]="or ";
        Question[11]="3 ";
        Question[12]="to ";
        Question[13]="ignore ";
        Question[14]=EventName;
    }

    string ReturnQuestion(int Index){
        return Question[Index];
    }

    /*vector<string> ReturnQuestion(){
 return Question;
    }*/

    void SetMode(char NewMode){
 if (NewMode == '0' || NewMode == '1' || NewMode == '2')
 Mode = NewMode;
}

    char ReturnMode(){
 return Mode;
    }

    string ReturnName(){
        return EventName;
    }
};

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

У меня проблема с объявлением массива объектов Event во втором объекте. При исследовании я натолкнулся на способы использования массива указателей на первый объект и некоторого оператора '->', который, как я предполагаю, связан с виртуальными функциями.

class WhatTheyWant{
    Event *events[2];
public:
    WhatTheyWant(){
        events[0]= new Event("Miss");
        events[1]= new Event("Dodge");
    }
};

Я очень неосведомлен об указателях, и я знаю, что в конечном итоге мне придется их изучать, но они - лучший путь или есть лучший.

Ответы [ 3 ]

1 голос
/ 14 ноября 2010

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

Если вы добавите конструктор по умолчанию в Event, вы можете сделать это как минимум двумя другими способами:

Если у вас всегда будет (небольшое) фиксированное количество объектов, вы можете просто объявить массивпостоянный размер:

Event events[2];

При этом автоматически создаются объекты при создании WhatTheyWant, поэтому вам просто нужно задать имена впоследствии:

WhatTheyWant() {
  events[0].SetName("Miss");
  events[1].SetName("Dodge");
}

Если вы хотите иметьПеременное число событий, вы можете объявить один указатель и динамически выделить массив объектов:

Event *events;

И вы, вероятно, могли бы дать число в качестве параметра конструктору:

WhatTheyWant(int numEvents) {
  events = new Event[numEvents];
  for (int i = 0; i < numEvents; i++)
    events[i]->SetName("...");
}

Кроме того, не имеет прямого отношения к вашему вопросу, но ваша переменная Mode будет лучше смоделирована с использованием перечисления вместо char.Использование enum проясняет, что на самом деле означает переменная, вместо использования таких значений, как 0, 1 и 2. Например:

public:
  enum ModeType { Ascending, Descending, None };
private:
  ModeType Mode;
public:
  Event() {
    ...
    Mode = Ascending;
  }
  void SetMode(ModeType NewMode) {
    Mode = NewMode;
  }
  ModeType ReturnMode() {
    return Mode;
  }
0 голосов
/ 14 ноября 2010

Вы можете использовать либо массив объектов, либо массив указателей.

Массив объектов идет как показано ниже.

class WhatTheyWant{ 
    Event events[2]; 
public: 
    WhatTheyWant()
    { 
       events[0] = Event("Miss");
       events[1] = Event("Dodge");
    } 
 }; 

Примечание: вам нужно добавить конструктор по умолчанию в ваш класс событий, чтобы скомпилировать вышеуказанный подход.

При вышеуказанном подходе вам не нужно заботиться об освобождении объектов Event. Всякий раз, когда объект WhatTheyWant уничтожается, объекты событий уничтожаются.

Массив указателей приближается так, как вы упомянули.

Но вам нужно позаботиться об освобождении выделенной памяти (если только вы не используете auto_ptr или какой-либо аналог c ++ 0x). Удаление должно происходить в деструкторе, как показано ниже.

class WhatTheyWant{ 
    Event *events[2]; 
public: 
    WhatTheyWant(){ 
        events[0]= new Event("Miss"); 
        events[1]= new Event("Dodge"); 
    } 
    ~WhatTheyWant()
    {
        delete events[0];
        delete events[1];
    }
};
0 голосов
/ 14 ноября 2010

В C ++ указатели похожи на массивы

в вашем классе WhatTheyWant, вы определяете закрытый член:

Event *events[2];

Это массив массивов (2D-массив) с переменной длиной(из массивов) и 2 элемента в каждом массиве.

и оператор '->' используется, когда вы хотите получить доступ к (члену какого-либо объекта), и это называется указателем объекта (указателем)который указывает на объект), но когда вы определяете обычную переменную объекта, вы используете '.'оператор.

Если у вас есть смелость и знания, чтобы использовать их, они очень полезны, но в целом они опасны, и поэтому новые языки имеют тенденцию идти управляемым путем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...